diff --git a/Src/A69WD/A69WD.csproj b/Src/A69WD/A69WD.csproj index 1d7d8be..9acc1eb 100644 --- a/Src/A69WD/A69WD.csproj +++ b/Src/A69WD/A69WD.csproj @@ -34,6 +34,10 @@ + + False + ..\..\..\..\_Library\SQLite\netFx40\sqlite-netFx40-binary-bundle-x64-2010-1.0.111.0\System.Data.SQLite.dll + @@ -45,13 +49,14 @@ - + + Form - + frmDownloader.cs - + @@ -66,7 +71,7 @@ Form1.cs - + frmDownloader.cs diff --git a/Src/A69WD/App.cs b/Src/A69WD/App.cs index 6494a02..5693afe 100644 --- a/Src/A69WD/App.cs +++ b/Src/A69WD/App.cs @@ -1,18 +1,71 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Windows.Forms; + + namespace A69WD { public class App { public static bool Retrive = true; - //public static ATLib.TextAppender RaccReport = null; - //public static ATLib.Data.DBTools DB = null; + public static A69WD.DBTools DB = null; - //public static ATLib.Plugin.iPlugin[] Plugs = null; + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) { + try { + // Common settings: + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + if ((args != null) && (args.Length > 0)) Retrive = false; + else Retrive = true; + + // Configura il logger dell'applicazione: + Logger.Configure(Cfg.Settings.PathFileLogs, Cfg.Settings.LogsFileSizeLimitKB, Cfg.Settings.LogsWinLoggerRef); + + // Configura il DB dell'applicazione + DB = new A69WD.DBTools(); + + // Start application: + Logger.Information(" - - - START Application - - - "); + if (DB.DB_ok) { + Application.Run(new frmDownloader()); + + Logger.Information(" - - - STOP Application - - - "); + + while (Logger.LogMissing() > 0) { + System.Threading.Thread.Sleep(25); + } + + // MRK: TODO rivedere la chiusura precedente per farla funzionare senza il tempo ma con il controllo totale dei thread. + + } else { + Logger.Error("Collegamento al DB non riuscito"); + MessageBox.Show("Applicazione abortita perchè non riesco ad aprire il DB", "Error"); + } + + + } catch (Exception ex) { + Logger.Log(new object[] { "Error Code: ER00000", "Errore in Main()", ex }); + } finally { + // Chiudo DB in memoria riportando sul DB di sistema le modifiche occorse: + if (DB != null) { + DB.Dispose(); + DB = null; + } + // Attesa per svuotamento logger: + while (Logger.LogMissing() > 0) { System.Threading.Thread.Sleep(100); } + } + } + + + + }//class App diff --git a/Src/A69WD/Data/DBTools.cs b/Src/A69WD/Data/DBTools.cs new file mode 100644 index 0000000..3cdcc5c --- /dev/null +++ b/Src/A69WD/Data/DBTools.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Data.SQLite; + + +namespace A69WD { + + + public class DBTools { + /* + + Database: A69WD: + + Tabella per storicizzare i link downloadati: + -------------------------------------------- + CREATE TABLE [LinksLog] ( + [URL] TEXT UNIQUE NOT NULL PRIMARY KEY, + [Tipo] TEXT NOT NULL, + [Status] INTEGER NOT NULL, + [LastUp] TIMESTAMP NOT NULL + ) + + */ + + + #region Class Fields & Property: + + public System.Data.SQLite.SQLiteConnection cn { get; set; } + public bool DB_ok { get; set; } + + #endregion + + #region Costruttore e distruttore: + + public DBTools() { + // Copio il DB dal file in memoria e mantengo la connessione per utilizzarla durante l'applicazione + object obj = new Object(); + lock (obj) { + System.Data.SQLite.SQLiteConnection conn = null; + #region MyRegion + + #endregion + // Check esistenza del DB dell'applicazione, altrimenti ne creo uno nuovo: + try { + if (!System.IO.File.Exists(System.IO.Path.Combine(Cfg.Settings.PathDB, Cfg.Settings.DBName))) { + // Creo un nuovo file di database e definisco le tabelle in uso. + conn = new SQLiteConnection(Cfg.Settings.DBConnectionString); + conn.Open(); + SQLiteCommand cmd = new SQLiteCommand(CreaA69DB(), conn); + int res = cmd.ExecuteNonQuery(); + if (res > 1) Logger.Log(new object[] { "Error Code: ER01012", string.Format("Possibile errore in DBTools() - cmd.ExecuteNonQuery(CREATE TABLE [CreaA69DB])={0}", res) }); + conn.Close(); + conn.Dispose(); + } + } catch (Exception ex) { + Logger.Log(new object[] { "Error Code: ER01010", "Errore in ATLib.Data.DBtools() durante il Check DB", ex }); + DB_ok = false; + return; + } finally { + if ((conn != null) && (conn.State != System.Data.ConnectionState.Closed)) conn.Close(); + } + // Riporto in memoria il DB per poter lavorare ad alta velocità. + try { + // Apro DB in memoria + if (cn == null) cn = new System.Data.SQLite.SQLiteConnection("data source=:memory:"); + cn.Open(); + // Creo tabelle in uso + SQLiteCommand cmd = new SQLiteCommand(CreaA69DB(), cn); + int res = cmd.ExecuteNonQuery(); + if (res > 1) Logger.Log(new object[] { "Error Code: ER01022", string.Format("Possibile errore in DBTools() - cmd.ExecuteNonQuery(CreaA69DB())={0}", res) }); + // Attach DB A69DB su File + cmd = new SQLiteCommand(string.Format("ATTACH '{0}' AS A69DBfile", System.IO.Path.Combine(Cfg.Settings.PathDB, Cfg.Settings.DBName)), cn); + res = cmd.ExecuteNonQuery(); + if (res > 1) Logger.Log(new object[] { "Error Code: ER01026b", string.Format("Possibile errore in DBTools() - cmd.ExecuteNonQuery(ATTACH {0} AS DBfile)", res) }); + // Copio i dati + cmd = new SQLiteCommand("INSERT INTO [LinksLog] SELECT * FROM A69DBfile.LinksLog", cn); + res = cmd.ExecuteNonQuery(); + if (res < 1) Logger.Information(string.Format("Info Code: IN01001 - Nessun LinksLog riportato sul DB in memoria.", res)); + // Detach del DB su File + } catch (Exception ex) { + Logger.Log(new object[] { "Error Code: ER01020", "Errore in ATLib.Data.DBtools() durante il trasferimento in memoria del DB", ex }); + DB_ok = false; + return; + } + // Memorizzo che il DB è stato correttamente caricato + DB_ok = true; + return; + } + } + + public bool Dispose() { + object obj = new Object(); + lock (obj) { + bool Res = false; + // Copio i valori creati: solo se il DB è OK: + if (!DB_ok) return Res; + try { + // Copio i dati saltando i doppioni + // Elimino i dati vecchi in A69DB: + SQLiteCommand cmd = new SQLiteCommand("DELETE FROM A69DBfile.LinksLog", cn); + int res = cmd.ExecuteNonQuery(); + if (res < 1) Logger.Information(string.Format("Info Code: IN03001 - Nessun LinksLog cancellato dal file del DB.", res)); + + // Inserisco i nuovi dati in A69DB: + cmd = new SQLiteCommand("INSERT INTO A69DBfile.LinksLog SELECT * FROM LinksLog", cn); + res = cmd.ExecuteNonQuery(); + if (res < 1) Logger.Information(string.Format("Info Code: IN03002 - Nessun LinksLog riportato sul file del DB.", res)); + + Res = true; + } catch (Exception ex) { + Logger.Log(new object[] { "Error Code: ER03000", "Errore in ATLib.Data.Dispose() durante il trasferimento in memoria del DB", ex }); + } finally { + if ((cn != null) && (cn.State != System.Data.ConnectionState.Closed)) cn.Close(); + } + // Eseguo la compressione del DB su file per evitare di usare troppa memoria: + System.Data.SQLite.SQLiteConnection conn = null; + // Check esistenza del DB dell'applicazione, altrimenti ne creo uno nuovo: + try { + conn = new SQLiteConnection(Cfg.Settings.DBConnectionString); + conn.Open(); + SQLiteCommand cmd = new SQLiteCommand("VACUUM", conn); + int res = cmd.ExecuteNonQuery(); + if (res > 1) Logger.Log(new object[] { "Error Code: IN03027", string.Format("Possibile errore in ATLib.Data.Dispose() - cmd.ExecuteNonQuery(VACUUM)={0}", res) }); + conn.Close(); + conn.Dispose(); + Res = Res && true; + } catch (Exception ex) { + Logger.Log(new object[] { "Error Code: ER03003", "Errore in ATLib.Data.Dispose() durante la compressione del DB", ex }); + Res = false; + } finally { + try { if ((conn != null) && (conn.State != System.Data.ConnectionState.Closed)) conn.Close(); } catch { } + } + return Res; + } + } + + private string CreaA69DB() { return "CREATE TABLE [LinksLog] ([URL] TEXT UNIQUE NOT NULL PRIMARY KEY,[Tipo] TEXT NOT NULL,[Status] INTEGER NOT NULL,[LastUp] TIMESTAMP NOT NULL)"; } + + #endregion + + + /// + /// Ricava dal DB tutti i dati + /// + /// Numero di link inseriti nell'engine. Un numero negativo se si è avuto un errore. + public long RetrieveLinks() { + // MRK: TODO: + // Può essere utile amplificare questa funzione in modo che si possa specificare quali link reinserire: + // Ad esempio dei filtri tipo: + // - solo link con Status pari a ErrorDownload o CancelDownload + // - solo link con Status pari a OnDownload + // - ecc... + + //return 0; // MRK: BYPASSATO TUTTO PER EVITARE CHE ALL'INIZIO CARICHI I LINK IN SOSPESO. + + object obj = new Object(); + lock (obj) { + long Res = 0; + System.Data.DataTable table = new System.Data.DataTable("LinksLog"); + try { + System.Data.SQLite.SQLiteCommand cmd = new SQLiteCommand("SELECT [URL], [Tipo], [Status], [LastUp] FROM [LinksLog] WHERE [Tipo]='Testo' AND [Status]<>4", cn); // Donwloaded = 4 + SQLiteDataReader rdr = cmd.ExecuteReader(); + while (rdr.Read()) { + string url = rdr["URL"] as string; + ATLinkState status = ATLinkState.ToDownload; + try { status = ((ATLinkState)((long)rdr["Status"])); } catch (Exception ex) { throw new Exception("ERRORE AFFABULANTE \n" + ex.Message); } + + ATLib.Net.ATLink lk = new ATLib.Net.ATLink(plugin, url, fileName, status); + ATLib.ATWDEngine.Instance.AddLink(lk); + Res++; + } + } catch (Exception ex) { + ATLib.Logger.Log(new object[] { "Error Code: DB07003", "Errore in ATLib.Data.DBTools.RetrieveLinks()", ex }); + if (Res > 0) Res = -1 * Res; + } + return Res; + } + } + + + + + } // class DBTools + + +}//namespace A69WD diff --git a/Src/A69WD/Net/eLinkState.cs b/Src/A69WD/Data/eLinkState.cs similarity index 100% rename from Src/A69WD/Net/eLinkState.cs rename to Src/A69WD/Data/eLinkState.cs diff --git a/Src/A69WD/frmDownloader.Designer.cs b/Src/A69WD/Net/frmDownloader.Designer.cs similarity index 97% rename from Src/A69WD/frmDownloader.Designer.cs rename to Src/A69WD/Net/frmDownloader.Designer.cs index a05bcd7..9b4fba6 100644 --- a/Src/A69WD/frmDownloader.Designer.cs +++ b/Src/A69WD/Net/frmDownloader.Designer.cs @@ -117,7 +117,6 @@ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(504, 74); - this.ControlBox = false; this.Controls.Add(this.btbPath); this.Controls.Add(this.tbPath); this.Controls.Add(this.btnClose); diff --git a/Src/A69WD/frmDownloader.cs b/Src/A69WD/Net/frmDownloader.cs similarity index 100% rename from Src/A69WD/frmDownloader.cs rename to Src/A69WD/Net/frmDownloader.cs diff --git a/Src/A69WD/frmDownloader.resx b/Src/A69WD/Net/frmDownloader.resx similarity index 100% rename from Src/A69WD/frmDownloader.resx rename to Src/A69WD/Net/frmDownloader.resx diff --git a/Src/A69WD/Program.cs b/Src/A69WD/Program.cs index e073d4c..4acf807 100644 --- a/Src/A69WD/Program.cs +++ b/Src/A69WD/Program.cs @@ -5,14 +5,14 @@ using System.Windows.Forms; namespace A69WD { static class Program { - /// - /// Punto di ingresso principale dell'applicazione. - /// - [STAThread] - static void Main() { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - } + ///// + ///// Punto di ingresso principale dell'applicazione. + ///// + //[STAThread] + //static void Main() { + // Application.EnableVisualStyles(); + // Application.SetCompatibleTextRenderingDefault(false); + // Application.Run(new Form1()); + //} } }