Export: Implement exporting and importing of sqlite3 and sql files
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Test / Run tests (push) Successful in 2m15s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Test / Run tests (push) Successful in 2m15s
				
			This commit is contained in:
		@@ -242,7 +242,9 @@ namespace Elwig {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public static async Task ReplaceDatabase(string filename) {
 | 
					        public static async Task ReplaceDatabase(string filename) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                await ElwigData.ImportDatabase(filename);
 | 
					                await Task.Run(async () => {
 | 
				
			||||||
 | 
					                    await Database.Import(filename);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
                MessageBox.Show("Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!", "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Information);
 | 
					                MessageBox.Show("Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!", "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Information);
 | 
				
			||||||
                ForceShutdown = true;
 | 
					                ForceShutdown = true;
 | 
				
			||||||
                Current.Shutdown();
 | 
					                Current.Shutdown();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										188
									
								
								Elwig/Helpers/Export/Database.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								Elwig/Helpers/Export/Database.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.IO.Compression;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Helpers.Export {
 | 
				
			||||||
 | 
					    public static class Database {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task ExportSqlite(string filename, bool zipFile) {
 | 
				
			||||||
 | 
					            if (zipFile) {
 | 
				
			||||||
 | 
					                File.Delete(filename);
 | 
				
			||||||
 | 
					                using var zip = ZipFile.Open(filename, ZipArchiveMode.Create);
 | 
				
			||||||
 | 
					                await zip.CheckIntegrity();
 | 
				
			||||||
 | 
					                var db = zip.CreateEntryFromFile(App.Config.DatabaseFile, "database.sqlite3", CompressionLevel.SmallestSize);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                File.Copy(App.Config.DatabaseFile, filename, true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task ExportSql(string filename, bool zipFile) {
 | 
				
			||||||
 | 
					            if (zipFile) {
 | 
				
			||||||
 | 
					                File.Delete(filename);
 | 
				
			||||||
 | 
					                using var zip = ZipFile.Open(filename, ZipArchiveMode.Create);
 | 
				
			||||||
 | 
					                var entry = zip.CreateEntry("database.sql", CompressionLevel.SmallestSize);
 | 
				
			||||||
 | 
					                using var stream = entry.Open();
 | 
				
			||||||
 | 
					                using var writer = new StreamWriter(stream, Utils.UTF8);
 | 
				
			||||||
 | 
					                await ExportSql(writer);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                using var stream = File.OpenWrite(filename);
 | 
				
			||||||
 | 
					                using var writer = new StreamWriter(stream, Utils.UTF8);
 | 
				
			||||||
 | 
					                await ExportSql(writer);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task ExportSql(StreamWriter writer) {
 | 
				
			||||||
 | 
					            using var cnx = await AppDbContext.ConnectAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var tables = new List<(string Name, string Sql)>();
 | 
				
			||||||
 | 
					            using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                cmd.CommandText = "SELECT name, sql FROM sqlite_schema WHERE type = 'table'";
 | 
				
			||||||
 | 
					                using var reader = await cmd.ExecuteReaderAsync();
 | 
				
			||||||
 | 
					                while (await reader.ReadAsync()) {
 | 
				
			||||||
 | 
					                    tables.Add((reader.GetString(0), reader.GetString(1)));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var applId = (long?)await AppDbContext.ExecuteScalar(cnx, "PRAGMA application_id") ?? 0;
 | 
				
			||||||
 | 
					            var userVers = (long?)await AppDbContext.ExecuteScalar(cnx, "PRAGMA user_version") ?? 0;
 | 
				
			||||||
 | 
					            var schemaVers = (long?)await AppDbContext.ExecuteScalar(cnx, "PRAGMA schema_version") ?? 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync($"-- Elwig database dump, {DateTime.Now:yyyy-MM-dd, HH:mm:ss}");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync($"-- {Environment.MachineName}, Zwst. {App.BranchName}, {App.Client.Name}");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync("BEGIN TRANSACTION;");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync("PRAGMA foreign_keys=OFF;");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync($"PRAGMA application_id=0x{applId:X8};");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync($"PRAGMA user_version=0x{userVers:X8};");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var t in tables) {
 | 
				
			||||||
 | 
					                await writer.WriteAsync(t.Sql);
 | 
				
			||||||
 | 
					                await writer.WriteLineAsync(";");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var columnNames = new List<string>();
 | 
				
			||||||
 | 
					                using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                    cmd.CommandText = $"PRAGMA table_info({t.Name})";
 | 
				
			||||||
 | 
					                    using var reader = await cmd.ExecuteReaderAsync();
 | 
				
			||||||
 | 
					                    while (await reader.ReadAsync()) {
 | 
				
			||||||
 | 
					                        columnNames.Add(reader.GetString(1));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                    cmd.CommandText = $"SELECT {string.Join(',', columnNames)} FROM {t.Name}";
 | 
				
			||||||
 | 
					                    using var reader = await cmd.ExecuteReaderAsync();
 | 
				
			||||||
 | 
					                    var columns = await reader.GetColumnSchemaAsync();
 | 
				
			||||||
 | 
					                    var values = new object[reader.FieldCount];
 | 
				
			||||||
 | 
					                    while (await reader.ReadAsync()) {
 | 
				
			||||||
 | 
					                        await writer.WriteAsync($"INSERT INTO {t.Name} VALUES (");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        reader.GetValues(values);
 | 
				
			||||||
 | 
					                        for (int i = 0; i < columns.Count; i++) {
 | 
				
			||||||
 | 
					                            var c = columns[i];
 | 
				
			||||||
 | 
					                            var v = values[i];
 | 
				
			||||||
 | 
					                            if (i > 0) await writer.WriteAsync(",");
 | 
				
			||||||
 | 
					                            if (v == null || v is DBNull) {
 | 
				
			||||||
 | 
					                                await writer.WriteAsync("NULL");
 | 
				
			||||||
 | 
					                            } else if (c.DataTypeName == "TEXT") {
 | 
				
			||||||
 | 
					                                await writer.WriteAsync($"'{v.ToString()?.Replace("'", "''")}'");
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                await writer.WriteAsync(v.ToString()?.Replace(',', '.'));
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        await writer.WriteLineAsync(");");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                cmd.CommandText = "SELECT sql FROM sqlite_schema WHERE type != 'table' AND sql IS NOT NULL";
 | 
				
			||||||
 | 
					                using var reader = await cmd.ExecuteReaderAsync();
 | 
				
			||||||
 | 
					                while (await reader.ReadAsync()) {
 | 
				
			||||||
 | 
					                    await writer.WriteAsync(reader.GetString(0));
 | 
				
			||||||
 | 
					                    await writer.WriteLineAsync(";");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync($"PRAGMA schema_version={schemaVers};");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync("PRAGMA foreign_keys=ON;");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync("COMMIT;");
 | 
				
			||||||
 | 
					            await writer.WriteLineAsync("VACUUM;");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task Import(string filename) {
 | 
				
			||||||
 | 
					            if (filename.EndsWith(".sql")) {
 | 
				
			||||||
 | 
					                await ImportSql(filename, false);
 | 
				
			||||||
 | 
					            } else if (filename.EndsWith(".sql.zip")) {
 | 
				
			||||||
 | 
					                await ImportSql(filename, true);
 | 
				
			||||||
 | 
					            } else if (filename.EndsWith(".sqlite3")) {
 | 
				
			||||||
 | 
					                await ImportSqlite(filename, false);
 | 
				
			||||||
 | 
					            } else if (filename.EndsWith(".sqlite3.zip")) {
 | 
				
			||||||
 | 
					                await ImportSqlite(filename, true);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                throw new ArgumentException($"Unknown file extension for importing: '{filename}'");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task ImportSql(string filename, bool zipFile = false) {
 | 
				
			||||||
 | 
					            if (zipFile) {
 | 
				
			||||||
 | 
					                using var zip = ZipFile.Open(filename, ZipArchiveMode.Read);
 | 
				
			||||||
 | 
					                await zip.CheckIntegrity();
 | 
				
			||||||
 | 
					                foreach (var entry in zip.Entries) {
 | 
				
			||||||
 | 
					                    if (entry.Name.EndsWith(".sql")) {
 | 
				
			||||||
 | 
					                        using var stream = entry.Open();
 | 
				
			||||||
 | 
					                        using var reader = new StreamReader(stream, Utils.UTF8);
 | 
				
			||||||
 | 
					                        await ImportSql(reader);
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                throw new FileFormatException("ZIP archive has to contain at least one .sql file");
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                using var stream = File.Open(filename, FileMode.Open);
 | 
				
			||||||
 | 
					                using var reader = new StreamReader(stream, Utils.UTF8);
 | 
				
			||||||
 | 
					                await ImportSql(reader);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task ImportSqlite(string filename, bool zipFile = false) {
 | 
				
			||||||
 | 
					            if (zipFile) {
 | 
				
			||||||
 | 
					                var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    using var zip = ZipFile.Open(filename, ZipArchiveMode.Read);
 | 
				
			||||||
 | 
					                    await zip.CheckIntegrity();
 | 
				
			||||||
 | 
					                    foreach (var entry in zip.Entries) {
 | 
				
			||||||
 | 
					                        if (entry.Name.EndsWith(".sqlite3")) {
 | 
				
			||||||
 | 
					                            entry.ExtractToFile(newName);
 | 
				
			||||||
 | 
					                            await ImportSqlite(newName);
 | 
				
			||||||
 | 
					                            return;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    throw new FileFormatException("ZIP archive has to contain at least one .sqlite3 file");
 | 
				
			||||||
 | 
					                } finally {
 | 
				
			||||||
 | 
					                    if (File.Exists(newName)) File.Delete(newName);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3");
 | 
				
			||||||
 | 
					            File.Move(App.Config.DatabaseFile, oldName, true);
 | 
				
			||||||
 | 
					            File.Move(filename, App.Config.DatabaseFile, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using var cnx = await AppDbContext.ConnectAsync();
 | 
				
			||||||
 | 
					            await AppDbContext.ExecuteBatch(cnx, "VACUUM");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task ImportSql(StreamReader reader) {
 | 
				
			||||||
 | 
					            var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
 | 
				
			||||||
 | 
					            File.Delete(newName);
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                using (var cnx = await AppDbContext.ConnectAsync($"Data Source=\"{newName}\"; Mode=ReadWriteCreate; Foreign Keys=False; Cache=Default; Pooling=False")) {
 | 
				
			||||||
 | 
					                    await AppDbContext.ExecuteBatch(cnx, await reader.ReadToEndAsync());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                await ImportSqlite(newName);
 | 
				
			||||||
 | 
					            } finally {
 | 
				
			||||||
 | 
					                if (File.Exists(newName)) File.Delete(newName);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -405,29 +405,6 @@ namespace Elwig.Helpers.Export {
 | 
				
			|||||||
            }.Export(filename);
 | 
					            }.Export(filename);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static async Task ImportDatabase(string filename) {
 | 
					 | 
				
			||||||
            var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3");
 | 
					 | 
				
			||||||
            var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
 | 
					 | 
				
			||||||
            try {
 | 
					 | 
				
			||||||
                using (var zip = ZipFile.Open(filename, ZipArchiveMode.Read)) {
 | 
					 | 
				
			||||||
                    await zip.CheckIntegrity();
 | 
					 | 
				
			||||||
                    var db = zip.GetEntry("database.sqlite3")!;
 | 
					 | 
				
			||||||
                    db.ExtractToFile(newName, true);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                File.Move(App.Config.DatabaseFile, oldName, true);
 | 
					 | 
				
			||||||
                File.Move(newName, App.Config.DatabaseFile, false);
 | 
					 | 
				
			||||||
            } finally {
 | 
					 | 
				
			||||||
                if (File.Exists(newName))
 | 
					 | 
				
			||||||
                    File.Delete(newName);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static void ExportDatabase(string filename) {
 | 
					 | 
				
			||||||
            File.Delete(filename);
 | 
					 | 
				
			||||||
            using var zip = ZipFile.Open(filename, ZipArchiveMode.Create);
 | 
					 | 
				
			||||||
            var db = zip.CreateEntryFromFile(App.Config.DatabaseFile, "database.sqlite3", CompressionLevel.SmallestSize);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public class ElwigExport {
 | 
					        public class ElwigExport {
 | 
				
			||||||
            public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; }
 | 
					            public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; }
 | 
				
			||||||
            public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; }
 | 
					            public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,17 @@
 | 
				
			|||||||
                    </MenuItem.Icon>
 | 
					                    </MenuItem.Icon>
 | 
				
			||||||
                </MenuItem>
 | 
					                </MenuItem>
 | 
				
			||||||
                <Separator/>
 | 
					                <Separator/>
 | 
				
			||||||
 | 
					                <MenuItem Header="Datenbank sichern..." Click="Menu_Database_Backup_Click">
 | 
				
			||||||
 | 
					                    <MenuItem.Icon>
 | 
				
			||||||
 | 
					                        <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
 | 
				
			||||||
 | 
					                    </MenuItem.Icon>
 | 
				
			||||||
 | 
					                </MenuItem>
 | 
				
			||||||
 | 
					                <MenuItem Header="Datenbank wiederherstellen..." Click="Menu_Database_Restore_Click">
 | 
				
			||||||
 | 
					                    <MenuItem.Icon>
 | 
				
			||||||
 | 
					                        <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
 | 
				
			||||||
 | 
					                    </MenuItem.Icon>
 | 
				
			||||||
 | 
					                </MenuItem>
 | 
				
			||||||
 | 
					                <Separator/>
 | 
				
			||||||
                <MenuItem Header="Abfragen stellen" Click="Menu_Database_Query_Click">
 | 
					                <MenuItem Header="Abfragen stellen" Click="Menu_Database_Query_Click">
 | 
				
			||||||
                    <MenuItem.Icon>
 | 
					                    <MenuItem.Icon>
 | 
				
			||||||
                        <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
 | 
					                        <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -146,6 +146,48 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            Mouse.OverrideCursor = null;
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void Menu_Database_Backup_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                var d = new SaveFileDialog() {
 | 
				
			||||||
 | 
					                    Title = "Datenbank sichern - Elwig",
 | 
				
			||||||
 | 
					                    FileName = $"database_{Utils.Today:yyyy-MM-dd}.sql.zip",
 | 
				
			||||||
 | 
					                    DefaultExt = "sql.zip",
 | 
				
			||||||
 | 
					                    Filter = "Komprimierte SQL-Datei (*.sql.zip)|*.sql.zip",
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                if (d.ShowDialog() == true) {
 | 
				
			||||||
 | 
					                    Mouse.OverrideCursor = Cursors.Wait;
 | 
				
			||||||
 | 
					                    await Task.Run(async () => {
 | 
				
			||||||
 | 
					                        await Database.ExportSql(d.FileName, true);
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } catch (Exception exc) {
 | 
				
			||||||
 | 
					                MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void Menu_Database_Restore_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                var d = new OpenFileDialog() {
 | 
				
			||||||
 | 
					                    Title = "Datenbank wiederherstellen - Elwig",
 | 
				
			||||||
 | 
					                    DefaultExt = "sql.zip",
 | 
				
			||||||
 | 
					                    Filter = "SQLite-Datenbank (*.sqlite3, *.sqlite3.zip, *.sql, *.sql.zip)|*.sqlite3;*.sqlite3.zip;*.sql;*.sql.zip",
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                if (d.ShowDialog() == true) {
 | 
				
			||||||
 | 
					                    var res = MessageBox.Show("Soll die Datenbank wirklich unwiederruflich durch die wiederhergestellte Version ersetzt werden?", "Datenbank wiederherstellen",
 | 
				
			||||||
 | 
					                        MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
 | 
				
			||||||
 | 
					                    if (res != MessageBoxResult.OK)
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Mouse.OverrideCursor = Cursors.Wait;
 | 
				
			||||||
 | 
					                    await App.ReplaceDatabase(d.FileName);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } catch (Exception exc) {
 | 
				
			||||||
 | 
					                MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void DownloadButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void DownloadButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            if (App.Config.SyncUrl == null)
 | 
					            if (App.Config.SyncUrl == null)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
@@ -243,21 +285,23 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            await Task.Run(async () => {
 | 
					            await Task.Run(async () => {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
 | 
					                    var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
 | 
				
			||||||
                    var file = data
 | 
					                    var files = data
 | 
				
			||||||
                        .Select(f => new {
 | 
					                        .Select(f => new {
 | 
				
			||||||
                            Name = f!["name"]!.AsValue().GetValue<string>(),
 | 
					                            Name = f!["name"]!.AsValue().GetValue<string>(),
 | 
				
			||||||
                            Timestamp = f!["modified"] != null && DateTime.TryParseExact(f!["modified"]!.AsValue().GetValue<string>(), "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt) ? dt : (DateTime?)null,
 | 
					                            Timestamp = f!["modified"] != null && DateTime.TryParseExact(f!["modified"]!.AsValue().GetValue<string>(), "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt) ? dt : (DateTime?)null,
 | 
				
			||||||
                            Url = f!["url"]!.AsValue().GetValue<string>(),
 | 
					                            Url = f!["url"]!.AsValue().GetValue<string>(),
 | 
				
			||||||
                            Size = f!["size"]!.AsValue().GetValue<long>(),
 | 
					                            Size = f!["size"]!.AsValue().GetValue<long>(),
 | 
				
			||||||
                        })
 | 
					                        })
 | 
				
			||||||
                        .Where(f => f.Name == "database.sqlite3.zip")
 | 
					                        .Where(f => f.Name.StartsWith("database.") && f.Name.EndsWith(".zip"))
 | 
				
			||||||
                        .FirstOrDefault();
 | 
					                        .OrderBy(f => f.Size)
 | 
				
			||||||
 | 
					                        .ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (file == null) {
 | 
					                    if (files.Count == 0) {
 | 
				
			||||||
                        MessageBox.Show("Die Datenbank wurde noch nicht vom Hauptgerät hochgeladen!", "Datenbank herunterladen",
 | 
					                        MessageBox.Show("Die Datenbank wurde noch nicht vom Hauptgerät hochgeladen!", "Datenbank herunterladen",
 | 
				
			||||||
                            MessageBoxButton.OK, MessageBoxImage.Error);
 | 
					                            MessageBoxButton.OK, MessageBoxImage.Error);
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    var file = files[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var res = MessageBox.Show($"Es wurde eine komprimierte Datenbank (ca. {file.Size / 1024 / 1024} MB) vom {file.Timestamp:dd.MM.yyyy, HH:mm} gefunden.\n\nWollen Sie wirklich die aktuelle Datenbank unwiederruflich\nlöschen und durch die gefundene ersetzen?\n\nDas kann zu Datenverlust führen!", "Datenbank herunterladen",
 | 
					                    var res = MessageBox.Show($"Es wurde eine komprimierte Datenbank (ca. {file.Size / 1024 / 1024} MB) vom {file.Timestamp:dd.MM.yyyy, HH:mm} gefunden.\n\nWollen Sie wirklich die aktuelle Datenbank unwiederruflich\nlöschen und durch die gefundene ersetzen?\n\nDas kann zu Datenverlust führen!", "Datenbank herunterladen",
 | 
				
			||||||
                        MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
 | 
					                        MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
 | 
				
			||||||
@@ -301,8 +345,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
					            Mouse.OverrideCursor = Cursors.Wait;
 | 
				
			||||||
            await Task.Run(async () => {
 | 
					            await Task.Run(async () => {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    var path = Path.Combine(App.TempPath, "database.sqlite3.zip");
 | 
					                    var path = Path.Combine(App.TempPath, "database.sql.zip");
 | 
				
			||||||
                    ElwigData.ExportDatabase(path);
 | 
					                    await Database.ExportSql(path, true);
 | 
				
			||||||
                    await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
 | 
					                    await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
 | 
				
			||||||
                    MessageBox.Show($"Hochladen der gesamten Datenbank erfolgreich!", "Datenbank hochladen",
 | 
					                    MessageBox.Show($"Hochladen der gesamten Datenbank erfolgreich!", "Datenbank hochladen",
 | 
				
			||||||
                        MessageBoxButton.OK, MessageBoxImage.Information);
 | 
					                        MessageBoxButton.OK, MessageBoxImage.Information);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,7 +38,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            IList<DbColumn> header;
 | 
					            IList<DbColumn> header;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            using (var cnx = await AppDbContext.ConnectAsync()) {
 | 
					            using (var cnx = await AppDbContext.ConnectAsync()) {
 | 
				
			||||||
                var cmd = cnx.CreateCommand();
 | 
					                using var cmd = cnx.CreateCommand();
 | 
				
			||||||
                cmd.CommandText = sqlQuery;
 | 
					                cmd.CommandText = sqlQuery;
 | 
				
			||||||
                using var reader = await cmd.ExecuteReaderAsync();
 | 
					                using var reader = await cmd.ExecuteReaderAsync();
 | 
				
			||||||
                header = await reader.GetColumnSchemaAsync();
 | 
					                header = await reader.GetColumnSchemaAsync();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user