private void ButtonOk_Click(object sender, EventArgs e) { DateTime? olderThan = null; int? progid = null; if (this.CheckByDate.Checked) { // Just pass the date part and discard the time olderThan = new DateTime(this.DateOlderThan.Value.Year, this.DateOlderThan.Value.Month, this.DateOlderThan.Value.Day); } if (this.CheckByProgramme.Checked) { progid = ((ComboNameValue<int>)this.ListProgrammes.SelectedItem).Value; } using (Status status = new Status()) { status.ShowDialog( this, () => { Model.Download.Cleanup(status, olderThan, progid, this.CheckOrphan.Checked, this.CheckPlayed.Checked, this.CheckKeepFiles.Checked); }); } }
private DataSearch() { Dictionary<string, string[]> tableCols = new Dictionary<string, string[]>(); tableCols.Add("downloads", new string[] { "name", "description" }); if (this.NeedRebuild(tableCols)) { // Close & clean up the connection used for testing dbConn.Close(); dbConn.Dispose(); dbConn = null; using (Status status = new Status()) { status.ShowDialog(delegate { this.RebuildIndex(status, tableCols); }); } } Model.Download.Added += this.Download_Added; Model.Download.Updated += this.Download_Updated; Model.Download.Removed += this.Download_Removed; DownloadManager.Progress += this.Download_Progress; }
private void ButtonOk_Click(object eventSender, EventArgs eventArgs) { if (string.IsNullOrEmpty(this.TextFileNameFormat.Text)) { Interaction.MsgBox("Please enter a value for the downloaded programme file name format.", MsgBoxStyle.Exclamation); this.TextFileNameFormat.Focus(); this.cancelClose = true; return; } bool formatChanged = Settings.FileNameFormat != this.TextFileNameFormat.Text; if (this.folderChanged || formatChanged) { string message = "Move existing downloads to \"" + this.TextSaveIn.Text + "\" and rename to new naming format?"; if (!formatChanged) { message = "Move existing downloads to \"" + this.TextSaveIn.Text + "\"?"; } else if (!this.folderChanged) { message = "Rename existing downloads to new naming format?"; } if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { using (Status status = new Status()) { status.ShowDialog( this, delegate { Model.Download.UpdatePaths(status, this.TextSaveIn.Text, this.TextFileNameFormat.Text); }); } } Settings.SaveFolder = this.TextSaveIn.Text; Settings.FileNameFormat = this.TextFileNameFormat.Text; } Settings.RunOnStartup = this.CheckRunOnStartup.Checked; Settings.RunAfterCommand = this.TextRunAfter.Text; Settings.ParallelDownloads = (int)this.NumberParallel.Value; Settings.RssServer = this.CheckRssServer.Checked; if (this.CheckRssServer.Checked) { Settings.RssServerPort = (int)this.NumberServerPort.Value; Settings.RssServerNumRecentEps = (int)this.NumberEpisodes.Value; } if (OsUtils.WinSevenOrLater()) { Settings.CloseToSystray = this.CheckCloseToSystray.Checked; } OsUtils.ApplyRunOnStartup(); }
private DataSearch() { Dictionary<string, string[]> tableCols = new Dictionary<string, string[]>(); tableCols.Add("downloads", new string[] { "name", "description" }); bool rebuild = false; if (!this.CheckIndex(tableCols)) { rebuild = true; } else { using (SQLiteCommand command = new SQLiteCommand("select count(*) from downloads", this.FetchDbConn())) { if (Model.Download.Count() != (long)command.ExecuteScalar()) { rebuild = true; } } } if (rebuild) { // Close & clean up the connection used for testing dbConn.Close(); dbConn.Dispose(); dbConn = null; using (Status status = new Status()) { status.ShowDialog(delegate { this.RebuildIndex(status, tableCols); }); } } Model.Download.Added += this.Download_Added; Model.Download.Updated += this.Download_Updated; Model.Download.Removed += this.Download_Removed; DownloadManager.Progress += this.Download_Progress; }
private void RebuildIndex(Status status, Dictionary<string, string[]> tableCols) { // Clean up the old index File.Delete(this.DatabasePath()); status.StatusText = "Building search index..."; status.ProgressBarMax = 100 * tableCols.Count; status.ProgressBarMarquee = false; lock (this.updateIndexLock) { using (SQLiteTransaction trans = this.FetchDbConn().BeginTransaction()) { // Create the index tables foreach (KeyValuePair<string, string[]> table in tableCols) { using (SQLiteCommand command = new SQLiteCommand(this.TableSql(table.Key, table.Value), this.FetchDbConn(), trans)) { command.ExecuteNonQuery(); } } status.StatusText = "Building search index for downloads..."; int progress = 1; List<Model.Download> downloadItems = Model.Download.FetchAll(); foreach (Model.Download downloadItem in downloadItems) { this.AddDownload(downloadItem); status.ProgressBarValue = (int)((progress / downloadItems.Count) * 100); progress += 1; } status.ProgressBarValue = 100; trans.Commit(); } } }
public static bool Startup() { const string DbFileName = "store.db"; string specDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DbFileName); string appDbPath = Path.Combine(FileUtils.GetAppDataFolder(), DbFileName); // Ensure that the template database exists if (!File.Exists(specDbPath)) { MessageBox.Show("The Radio Downloader template database was not found at '" + specDbPath + "'." + Environment.NewLine + Environment.NewLine + "Try repairing the Radio Downloader installation or installing the latest version from nerdoftheherd.com", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop); return false; } // Migrate old (pre 0.26) version databases from www.nerdoftheherd.com -> NerdoftheHerd.com string oldDbPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "www.nerdoftheherd.com"), Application.ProductName), DbFileName); if (File.Exists(oldDbPath) && !File.Exists(appDbPath)) { File.Move(oldDbPath, appDbPath); } // Test if there is an existing application database if (!File.Exists(appDbPath)) { // Start with a copy of the template database File.Copy(specDbPath, appDbPath); // Set the current database version in the new database Settings.DatabaseVersion = Database.CurrentDbVersion; } else { // Start a transaction so we can roll back a half-completed upgrade on error using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction())) { try { // Perform a check and automatic update of the database table structure using (SQLiteConnection specConn = new SQLiteConnection("Data Source=" + specDbPath + ";Version=3;New=False;Read Only=True")) { specConn.Open(); UpdateStructure(specConn, Database.FetchDbConn()); } // Perform any updates required which were not handled by UpdateStructure switch (Settings.DatabaseVersion) { case 4: // Clear error details previously serialised as XML using (SQLiteCommand command = new SQLiteCommand("update downloads set errordetails=null where errortype=@errortype", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("errortype", ErrorType.UnknownError)); command.ExecuteNonQuery(); } break; case Database.CurrentDbVersion: // Nothing to do, this is the current version. break; } // Set the current database version Settings.DatabaseVersion = Database.CurrentDbVersion; } catch (SQLiteException) { transMon.Trans.Rollback(); throw; } transMon.Trans.Commit(); } } // Prune the database once a week if (Settings.LastPrune.AddDays(7) < DateTime.Now) { using (Status status = new Status()) { status.ShowDialog(delegate { Prune(status); }); } } // Vacuum the database every three months if (Settings.LastVacuum.AddMonths(3) < DateTime.Now) { using (Status status = new Status()) { status.ShowDialog(delegate { Vacuum(status); }); } } return true; }
private static void Vacuum(Status status) { status.StatusText = "Compacting database. This may take several minutes..."; // Make SQLite recreate the database to reduce the size on disk and remove fragmentation lock (Database.DbUpdateLock) { using (SQLiteCommand command = new SQLiteCommand("vacuum", FetchDbConn())) { command.ExecuteNonQuery(); } Settings.LastVacuum = DateTime.Now; } }
private static void Prune(Status status) { lock (Database.DbUpdateLock) { using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction())) { status.StatusText = "Pruning episode images..."; // Set image to null for unavailable episodes, except: // - episodes in the downloads list // - the most recent episode for subscriptions or favourites (as this may be used as the programme image) using (SQLiteCommand command = new SQLiteCommand("update episodes set image=null where epid in (select e1.epid from episodes as e1 left outer join downloads on e1.epid=downloads.epid where available=0 and image is not null and downloads.epid is null and ((not (exists(select 1 from subscriptions where subscriptions.progid=e1.progid) or exists(select 1 from favourites where favourites.progid=e1.progid))) or exists(select 1 from episodes as e2 where e1.progid=e2.progid and image is not null and e2.date > e1.date)))", FetchDbConn())) { command.ExecuteNonQuery(); } status.StatusText = "Cleaning up unused images..."; // Remove images which are now no-longer referenced by a programme or episode using (SQLiteCommand command = new SQLiteCommand("delete from images where imgid in (select imgid from images left outer join programmes on imgid=programmes.image left outer join episodes on imgid=episodes.image where programmes.image is null and episodes.image is null)", FetchDbConn())) { command.ExecuteNonQuery(); } transMon.Trans.Commit(); } Settings.LastPrune = DateTime.Now; } }
public static bool Startup() { const string DbFileName = "store.db"; string specDbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DbFileName); string appDbPath = Path.Combine(FileUtils.GetAppDataFolder(), DbFileName); // Ensure that the template database exists if (!File.Exists(specDbPath)) { MessageBox.Show("The Radio Downloader template database was not found at '" + specDbPath + "'." + Environment.NewLine + Environment.NewLine + "Try repairing the Radio Downloader installation or installing the latest version from nerdoftheherd.com", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop); return false; } using (SQLiteConnection specConn = new SQLiteConnection("Data Source=" + specDbPath + ";Version=3;New=False;Read Only=True")) { specConn.Open(); using (SQLiteCommand command = new SQLiteCommand("pragma integrity_check(1)", specConn)) { string result = (string)command.ExecuteScalar(); if (result.ToUpperInvariant() != "OK") { MessageBox.Show("The Radio Downloader template database at '" + specDbPath + "' appears to be corrupted." + Environment.NewLine + Environment.NewLine + "Try repairing the Radio Downloader installation or installing the latest version from nerdoftheherd.com", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop); return false; } } // Migrate old (pre 0.26) version databases from www.nerdoftheherd.com -> NerdoftheHerd.com string oldDbPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "www.nerdoftheherd.com"), Application.ProductName), DbFileName); if (File.Exists(oldDbPath) && !File.Exists(appDbPath)) { File.Move(oldDbPath, appDbPath); } // Test if there is an existing application database if (!File.Exists(appDbPath)) { // Start with a copy of the template database File.Copy(specDbPath, appDbPath); // Set the current database version in the new database Settings.DatabaseVersion = CurrentDbVersion; } else { using (SQLiteCommand command = new SQLiteCommand("pragma integrity_check(1)", FetchDbConn())) { string result = (string)command.ExecuteScalar(); if (result.ToUpperInvariant() != "OK") { if (MessageBox.Show("Unfortunately Radio Downloader cannot start because your database has become corrupted." + Environment.NewLine + Environment.NewLine + "Would you like to view some help about resolving this issue?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.Yes) { OsUtils.LaunchUrl(new Uri("https://nerdoftheherd.com/tools/radiodld/help/corrupt-database"), "corruptdb"); } return false; } } // Start a transaction so we can roll back a half-completed upgrade on error using (SQLiteMonTransaction transMon = new SQLiteMonTransaction(FetchDbConn().BeginTransaction())) { try { // Perform a check and automatic update of the database table structure UpdateStructure(specConn, FetchDbConn()); // Perform any updates required which were not handled by UpdateStructure switch (Settings.DatabaseVersion) { case 4: // Clear error details previously serialised as XML using (SQLiteCommand command = new SQLiteCommand("update downloads set errordetails=null where errortype=@errortype", FetchDbConn())) { command.Parameters.Add(new SQLiteParameter("errortype", ErrorType.UnknownError)); command.ExecuteNonQuery(); } break; case CurrentDbVersion: // Nothing to do, this is the current version. break; } // Set the current database version Settings.DatabaseVersion = CurrentDbVersion; } catch (SQLiteException) { transMon.Trans.Rollback(); throw; } transMon.Trans.Commit(); } } } // Prune the database once a week if (Settings.LastPrune.AddDays(7) < DateTime.Now) { using (Status status = new Status()) { status.ShowDialog(() => { Prune(status); }); } } // Vacuum the database every three months if (Settings.LastVacuum.AddMonths(3) < DateTime.Now) { using (Status status = new Status()) { status.ShowDialog(() => { Vacuum(status); }); } } return true; }