using Comal.Stores; using InABox.Clients; using InABox.Core; using InABox.Database; using InABox.Database.SQLite; using InABox.DynamicGrid; using InABox.Wpf; using InABox.WPF; using PRSServices; using Stripe.Treasury; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace PRSServer.Forms.Version9Update; public class UpdateDatabaseFilesGridItem : BaseObject { public string Name { get; set; } public string FileName { get; set; } public IProviderFactory ProviderFactory { get; set; } public VersionNumber Version { get; set; } public string VersionText => Version?.ToString() ?? ""; public bool NeedsUpdate => Version is not null && Version.MajorVersion < 9; } public class UpdateDatabaseFilesGrid : DynamicItemsListGrid { private static readonly BitmapImage? _warning = Properties.Resources.warning.AsBitmapImage(); private static readonly BitmapImage? _tick = Properties.Resources.tick.AsBitmapImage(); protected override void Init() { base.Init(); ActionColumns.Add(new DynamicImageColumn(GetImage, UpdateClick) { ToolTip = UpdateToolTip }); } private FrameworkElement? UpdateToolTip(DynamicActionColumn column, CoreRow? row) { if(row is null) { return null; } var item = LoadItem(row); if (item.NeedsUpdate) { return column.TextToolTip($"This database is currently version {item.VersionText} and needs updating to version 9."); } else { return null; } } protected override DynamicGridColumns LoadColumns() { var columns = new DynamicGridColumns(); columns.Add(x => x.Name); columns.Add(x => x.VersionText, caption: "Current Version"); return columns; } protected override void DoReconfigure(DynamicGridOptions options) { options.Clear(); } private bool UpdateClick(CoreRow? row) { if (row is null) return false; var item = LoadItem(row); if (!item.NeedsUpdate) return false; var currentVersion = DbFactory.GetDatabaseVersion(item.ProviderFactory); if(currentVersion.MajorVersion >= 9) { item.Version = currentVersion; return true; } var task = Task.Run(() => { DbFactory.Stores = CoreUtils.TypeList( AppDomain.CurrentDomain.GetAssemblies(), myType => myType.IsClass && !myType.IsAbstract && !myType.IsGenericType && myType.GetInterfaces().Contains(typeof(IStore)) ).ToArray(); DbFactory.DefaultStore = typeof(BaseStore<>); var factory = new SQLiteProviderFactory(item.FileName); DbFactory.ProviderFactory = factory; DbFactory.Start(); // Doing this will run all the update scripts. factory.InitializeNulls(); }); var window = Window.GetWindow(this); var console = new UpdateConsole("Console"); console.Top = window.Top; console.Left = window.Left + window.Width + 2; console.Height = window.Height; console.Loaded += (_, args) => { var worker = new BackgroundWorker(); window.IsEnabled = false; worker.DoWork += (o, e) => { task.Wait(); }; worker.RunWorkerCompleted += (o, e) => console.Close(); worker.RunWorkerAsync(); }; console.ShowDialog(); try { task.Wait(); } catch(Exception e) { MessageWindow.ShowError("An error occurred while trying to update this database.", e); } window.IsEnabled = true; currentVersion = DbFactory.GetDatabaseVersion(item.ProviderFactory); item.Version = currentVersion; return true; } private BitmapImage? GetImage(CoreRow? row) { if (row is null) return _tick; return LoadItem(row).NeedsUpdate ? _warning : _tick; } } /// /// Interaction logic for UpdateDatabaseFiles.xaml /// public partial class UpdateDatabaseFiles : Window { public UpdateDatabaseFiles() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { LoadData(); } private void LoadData() { Progress.ShowModal("Loading Data", progress => { var table = new CoreTable(); table.LoadColumns(typeof(Server)); var sections = PRSService.GetConfiguration().LoadAll(); foreach (var section in sections.Where(x => x.Value.Type == ServerType.Database)) { var properties = section.Value.DeserializeServerProperties(); if (properties is not DatabaseServerProperties databaseProperties) continue; Grid.Items.Add(new() { Name = databaseProperties.Name, FileName = databaseProperties.FileName, }); } var tasks = Grid.Items.ToArray(LoadProvider); Task.WaitAll(tasks); foreach(var (item, task) in Grid.Items.Zip(tasks)) { item.ProviderFactory = task.Result; item.Version = DbFactory.GetDatabaseVersion(item.ProviderFactory); } }); Grid.Refresh(true, true); } private Task LoadProvider(UpdateDatabaseFilesGridItem item) { return Task.Run(() => { IProviderFactory factory = new SQLiteProviderFactory(item.FileName); factory.Start(); return factory; }); } private void Proceed_Click(object sender, RoutedEventArgs e) { if(Grid.Items.Any(x => x.NeedsUpdate)) { if(!MessageWindow.ShowYesNo("Some database files have not been updated to version 9! If you proceed, these " + "databases will not work anymore. Are you sure you wish to proceed?", "Unupdated files")) { return; } } DialogResult = true; } private void Cancel_Click(object sender, RoutedEventArgs e) { DialogResult = false; } }