Files
A69WD/Src/A69WD/Data/DBTools.cs
T
CSiCoAlm d092d4a65d Inserisco nel DB le tabelle per i racconti
- Inserito nel DB le tabelle per l'archivio dei racconti
- Inserito gestione in memoria del DB (manca ottimizzazione lasciando l'archivio su file come fatto per ATDB)
- Inserito classe cRac per rappresentare un racconto

ToDo:
- Aggiungere gestione parallela della FIFO secondo vecchi modello per aumentare il feedback alla UI
- Inserire anche l'estrazione dei racconti
- Per ora metto tutto il DB in memoria, poi dovrò ottimizzare come su ATDB
2025-12-27 15:12:42 +01:00

867 lines
62 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SQLite;
using A69WD.Net;
using System.Drawing;
namespace A69WD {
public class DBTools {
/*
*
* Tabella per storicizzare i link downloadati:
* --------------------------------------------
* CREATE TABLE [LinksLog] ( /* Tabella per salvare il lavoro fatto sui link * /
* [LinkURL] TEXT UNIQUE NOT NULL PRIMARY KEY, /* URL del link * /
* [FileName] TEXT UNIQUE NOT NULL, /* Nome del file su cui salvo quanto downloadato * /
* [PlugID] TEXT NOT NULL, /* ID del plugin utilizzato per gestire questo particolare link * /
* [Fields] INTEGER NOT NULL, /* Campo in cui salvo tutti i dati significativi sul link, separati fra loro da -|- * /
* [Status] INTEGER NOT NULL, /* Stato della lavorazione * /
* [LastUpdate] TIMESTAMP NOT NULL /* Timestamp all'ultimo aggiornamento del record * /
* )
*
*/
#region Class Fields & Property: cn, DB_ok, objLock
/// <summary>
/// Connessione al DB
/// </summary>
public System.Data.SQLite.SQLiteConnection cn { get; set; }
/// <summary>
/// Indicatore che il DB è ready
/// </summary>
public bool DB_ok { get; set; }
/// <summary>
/// Oggetto per la sincronizzazione fra i threads:
/// </summary>
internal readonly object objLock = new object();
#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;
// 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 cartella se non esiste
if (!System.IO.Directory.Exists(Cfg.Settings.PathDB)) { System.IO.Directory.CreateDirectory(Cfg.Settings.PathDB); }
// 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(false), 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 A69DBfile)", 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));
cmd = new SQLiteCommand("INSERT INTO [Voti] SELECT * FROM A69DBfile.Voti", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01002 - Nessun Voti riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Racconti] SELECT * FROM A69DBfile.Racconti", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01003 - Nessun Racconti riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Autori] SELECT * FROM A69DBfile.Autori", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01004 - Nessun Autori riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Origini] SELECT * FROM A69DBfile.Origini", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01005 - Nessun Origini riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Tags] SELECT * FROM A69DBfile.Tags", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01006 - Nessun Tags riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Notes] SELECT * FROM A69DBfile.Notes", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01007 - Nessun Notes riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Trame] SELECT * FROM A69DBfile.Trame", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01008 - Nessun Trame riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Segnalini] SELECT * FROM A69DBfile.Segnalini", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Segnalini riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Users] SELECT * FROM A69DBfile.Users", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Users riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Links_Rac_Aut] SELECT * FROM A69DBfile.Links_Rac_Aut", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Links_Rac_Aut riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Links_Rac_Not] SELECT * FROM A69DBfile.Links_Rac_Not", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Links_Rac_Not riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Links_Rac_Tag] SELECT * FROM A69DBfile.Links_Rac_Tag", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Links_Rac_Tag riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Links_Rac_Ori] SELECT * FROM A69DBfile.Links_Rac_Ori", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Links_Rac_Ori riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Links_Rac_Vot] SELECT * FROM A69DBfile.Links_Rac_Vot", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Links_Rac_Vot riportato sul DB in memoria.", res));
cmd = new SQLiteCommand("INSERT INTO [Links_Rac_Sng] SELECT * FROM A69DBfile.Links_Rac_Sng", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN01009 - Nessun Links_Rac_Sng 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 {
// Detach del DB su File
SQLiteCommand cmd = new SQLiteCommand("DETACH DATABASE A69DBfile", cn);
int res = cmd.ExecuteNonQuery();
if (res > 1) Logger.Log(new object[] { "Error Code: ER01026", string.Format("Possibile errore in DBTools() - cmd.ExecuteNonQuery(DETACH {0} AS A69DBfile)", res) });
// Elimino il file rinominandolo per backup
string FullNameDB = System.IO.Path.Combine(Cfg.Settings.PathDB,Cfg.Settings.DBName);
string FullNameBkDB = FullNameDB.Replace(".db","_BK_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".db");
System.IO.File.Move(FullNameDB, FullNameBkDB);
// Creo nuovo file vuoto su cui riportare i dati dalla memoria:
using (SQLiteConnection cnTmp = new SQLiteConnection(Cfg.Settings.DBConnectionString)) {
cnTmp.Open();
cmd = new SQLiteCommand(CreaA69DB(false), cnTmp);
res = cmd.ExecuteNonQuery();
if (res < 0) Logger.Log(new object[] { "Error Code: ER03011", string.Format("Possibile errore in DBTools() - cmd.ExecuteNonQuery(CreaDB(false, false))={0}", res) });
cnTmp.Close();
cnTmp.Dispose();
}
// Attach DB 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: ER03026", string.Format("Possibile errore in DBTools() - cmd.ExecuteNonQuery(ATTACH {0} AS A69DBfile)", res) });
// Copio i dati
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));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Voti SELECT * FROM Voti", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03002 - Nessun Voti riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Racconti SELECT * FROM [Racconti]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03003 - Nessun Racconti riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Autori SELECT * FROM [Autori]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03004 - Nessun Autori riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Origini SELECT * FROM [Origini]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03005 - Nessun Origini riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Tags SELECT * FROM [Tags]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03006 - Nessun Tags riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Notes SELECT * FROM [Notes]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03007 - Nessun Notes riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Trame SELECT * FROM [Trame]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03008 - Nessun Trame riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Segnalini SELECT * FROM [Segnalini]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03009 - Nessun Segnalini riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Users SELECT * FROM [Users]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03010 - Nessun Users riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Links_Rac_Aut SELECT * FROM [Links_Rac_Aut]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03011 - Nessun Links_Rac_Aut riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Links_Rac_Not SELECT * FROM [Links_Rac_Not]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03012 - Nessun Links_Rac_Not riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Links_Rac_Tag SELECT * FROM [Links_Rac_Tag]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03013 - Nessun Links_Rac_Tag riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Links_Rac_Ori SELECT * FROM [Links_Rac_Ori]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03014 - Nessun Links_Rac_Ori riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Links_Rac_Vot SELECT * FROM [Links_Rac_Vot]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03015 - Nessun Links_Rac_Vot riportato sul file DB.", res));
cmd = new SQLiteCommand("INSERT INTO A69DBfile.Links_Rac_Sng SELECT * FROM [Links_Rac_Sng]", cn);
res = cmd.ExecuteNonQuery();
if (res < 1) Logger.Information(string.Format("Info Code: IN03016 - Nessun Links_Rac_Sng riportato sul file DB.", res));
// Detach del DB su File
cmd = new SQLiteCommand("DETACH DATABASE A69DBfile", cn);
res = cmd.ExecuteNonQuery();
if (res > 1) Logger.Log(new object[] { "Error Code: ER01026", string.Format("Possibile errore in DBTools() - cmd.ExecuteNonQuery(DETACH {0} AS A69DBfile)", 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();
conn = null;
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(bool FixedData = true) {
StringBuilder sb = new StringBuilder();
#region Definisco il DB dalla struttura sopra riportata
sb.AppendLine("------------------------------------------------------------------------------");
sb.AppendLine("-- ");
sb.AppendLine("-- Creazione delle tabelle principali:");
sb.AppendLine("-- ");
sb.AppendLine("-- ");
sb.AppendLine("CREATE TABLE [LinksLog] ( /* Tabella per salvare il lavoro fatto sui link */ ");
sb.AppendLine(" [LinkURL] TEXT UNIQUE NOT NULL PRIMARY KEY, /* URL del link */");
sb.AppendLine(" [FileName] TEXT UNIQUE NOT NULL, /* Nome del file su cui salvo quanto downloadato */ ");
sb.AppendLine(" [PlugID] TEXT NOT NULL, /* ID del plugin utilizzato per gestire questo particolare link */ ");
sb.AppendLine(" [Fields] INTEGER NOT NULL, /* Campo in cui salvo tutti i dati significativi sul link, separati fra loro da -|- */ ");
sb.AppendLine(" [Status] INTEGER NOT NULL, /* Stato della lavorazione */ ");
sb.AppendLine(" [LastUpdate] TIMESTAMP NOT NULL /* Timestamp all'ultimo aggiornamento del record */ ");
sb.AppendLine("); ");
sb.AppendLine("-- ");
sb.AppendLine("-- ");
sb.AppendLine("------------------------------------------------------------------------------");
sb.AppendLine(" -- ");
sb.AppendLine(" CREATE TABLE [Racconti] ( -- COMMENT ");
sb.AppendLine(" [IDrac] INTEGER PRIMARY KEY AUTOINCREMENT, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [Title] TEXT NOT NULL DEFAULT 'Unknown', -- COMMENT 'Titolo del racconto' ");
sb.AppendLine(" [SubTitle] TEXT NOT NULL DEFAULT '', -- COMMENT 'Sottotitolo del racconto' ");
sb.AppendLine(" [Creato] TEXT NOT NULL DEFAULT '2000/12/31', -- COMMENT 'Data di creazione del racconto' ");
sb.AppendLine(" [Aggiornato] TEXT NOT NULL DEFAULT '2000/12/31' -- COMMENT 'Data dell''ultima modifica al racconto' ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Autori] ( -- COMMENT='Tabella con tutti gli Autori dei Racconti dell''archivio.' ");
sb.AppendLine(" [IDaut] INTEGER PRIMARY KEY AUTOINCREMENT, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [Autore] TEXT NON NULL DEFAULT 'Unknown', -- COMMENT 'Nickname dell autore', ");
sb.AppendLine(" UNIQUE(Autore) ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Notes] ( -- COMMENT 'Tabella per rappresentare tramite coppia key-value delle note da associare ad un racconto. Da utilizzare per salvare il link da cui ho downloadato il racconto, oppure l''eventuale riassunto, o altro.' ");
sb.AppendLine(" [IDnot] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo della nota' ");
sb.AppendLine(" [NKey] TEXT NON NULL DEFAULT 'Nota', -- COMMENT 'Nota Key: Identificativo del tipo di nota: Resume, Link, OriginalID, ...' ");
sb.AppendLine(" [NVal] TEXT NON NULL DEFAULT '', -- COMMENT 'Nota Value: valore della nota' ");
sb.AppendLine(" UNIQUE(NKey, NVal) ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Origini] ( -- COMMENT 'Tabella con tutte le possibili Origini dei racconti.' ");
sb.AppendLine(" [IDori] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del origine' ");
sb.AppendLine(" [Origine] TEXT NON NULL DEFAULT 'Unknown', -- COMMENT 'Origine da cui ho preso il racconto' ");
sb.AppendLine(" UNIQUE(Origine) ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Segnalini] ( -- COMMENT ");
sb.AppendLine(" [IDsng] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del segnalino' ");
sb.AppendLine(" [Linea] INTEGER NOT NULL DEFAULT 0, -- COMMENT 'Indice della linea che si vuole segnalare (0 inizio racconto)' ");
sb.AppendLine(" [Segnalino] TEXT NON NULL DEFAULT 'Read', -- COMMENT 'Descrizione del segnalino per semplice comprensione (Read pe ril segnalino automatico con il punto di lettura)' ");
sb.AppendLine(" UNIQUE(Linea, Segnalino) ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Tags] ( -- COMMENT 'Tabella con tutte i tag che vogliamo associare ai Racconti.' ");
sb.AppendLine(" [IDtag] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del Tag' ");
sb.AppendLine(" [Tag] TEXT NON NULL COLLATE NOCASE, -- COMMENT 'Nome descrittivo del Tag' ");
sb.AppendLine(" UNIQUE(Tag) ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Trame] ( -- COMMENT 'Tabella con tutte le Trame dei Racconti.' ");
sb.AppendLine(" [IDtra] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo della trama' ");
sb.AppendLine(" [IDrac] INTEGER NON NULL, -- COMMENT 'Identificativo del racconto a cui la trama corrisponde (univoco perchè solo una trama per racconto). Rappresenta la relazione 1-1 fra Racconti-Trame' ");
sb.AppendLine(" [Trama] TEXT NON NULL, -- COMMENT 'Trama del racconto' ");
sb.AppendLine(" UNIQUE(IDrac), ");
sb.AppendLine(" FOREIGN KEY(`IDrac`) REFERENCES `Racconti`(`IDrac`) ON DELETE CASCADE ON UPDATE CASCADE ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Voti] ( -- COMMENT 'Tabella con tutti i possibili Voti associabili ai Racconti.' ");
sb.AppendLine(" [IDvot] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del voto' ");
sb.AppendLine(" [Rating] INTEGER CHECK (Rating>-1 AND Rating<11), -- COMMENT 'Valore del voto per statistiche' ");
sb.AppendLine(" [Voto] TEXT NON NULL COLLATE NOCASE, -- COMMENT 'Voto da attribuire ad un racconto' ");
sb.AppendLine(" UNIQUE(Voto) ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Users] ( -- COMMENT 'Elenco degli utenti abilitati della web application' ");
sb.AppendLine(" [IDusr] INTEGER PRIMARY KEY AUTOINCREMENT, -- COMMENT 'Identificativo dell''utente' ");
sb.AppendLine(" [Username] TEXT NOT NULL, -- COMMENT 'Username di identificazione dell''utente. Viene scelto dall''utente stesso al momento della registrazione' ");
sb.AppendLine(" [Password] TEXT NOT NULL, -- COMMENT 'Hash della password scelta dall''utente' ");
sb.AppendLine(" [Level] INTEGER NOT NULL DEFAULT 0, -- COMMENT 'Livello dell''utente nella web application. Di default è posto a 0 e solo l''amministratore può variarlo' ");
sb.AppendLine(" UNIQUE(Username) ");
sb.AppendLine(" ); ");
sb.AppendLine(" -- ");
sb.AppendLine(" -- Creazione delle tabelle per rappresentare i link fra i record ");
sb.AppendLine(" -- ");
sb.AppendLine(" CREATE TABLE [Links_Rac_Aut] ( -- COMMENT 'Tabella per rappresentare la relazione Molti-Molti fra i Racconti e i propri Autori.' ");
sb.AppendLine(" [IDlnk] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del link fra Racconti-Autori' ");
sb.AppendLine(" [IDrac] INTEGER NOT NULL, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [IDaut] INTEGER NOT NULL, -- COMMENT 'Identificativo dell''autore' ");
sb.AppendLine(" UNIQUE(IDrac, IDaut), ");
sb.AppendLine(" FOREIGN KEY(`IDrac`) REFERENCES `Racconti`(`IDrac`) ON DELETE CASCADE ON UPDATE CASCADE, ");
sb.AppendLine(" FOREIGN KEY(`IDaut`) REFERENCES `Autori`(`IDaut`) ON DELETE CASCADE ON UPDATE CASCADE ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE Links_Rac_Not ( -- COMMENT 'Tabella per rappresentare la relazione Molti-Molti fra i Racconti e le note (coppie key-Value).' ");
sb.AppendLine(" [IDlnk] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del link fra Racconti-Notes' ");
sb.AppendLine(" [IDrac] INTEGER NOT NULL, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [IDnot] INTEGER NOT NULL, -- COMMENT 'Identificativo della nota' ");
sb.AppendLine(" UNIQUE(IDrac, IDnot), ");
sb.AppendLine(" FOREIGN KEY(`IDrac`) REFERENCES `Racconti`(`IDrac`) ON DELETE CASCADE ON UPDATE CASCADE, ");
sb.AppendLine(" FOREIGN KEY(`IDnot`) REFERENCES `Notes`(`IDnot`) ON DELETE CASCADE ON UPDATE CASCADE ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Links_Rac_Tag] ( -- COMMENT 'Tabella per rappresentare la relazione Molti-Molti fra i Racconti e le propietà.' ");
sb.AppendLine(" [IDlnk] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del link fra Racconti-Tags' ");
sb.AppendLine(" [IDrac] INTEGER NOT NULL, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [IDtag] INTEGER NOT NULL, -- COMMENT 'Identificativo della propietà' ");
sb.AppendLine(" UNIQUE(IDrac, IDtag), ");
sb.AppendLine(" FOREIGN KEY(`IDrac`) REFERENCES `Racconti`(`IDrac`) ON DELETE CASCADE ON UPDATE CASCADE, ");
sb.AppendLine(" FOREIGN KEY(`IDtag`) REFERENCES `Tags`(`IDtag`) ON DELETE CASCADE ON UPDATE CASCADE ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Links_Rac_Ori] ( -- COMMENT 'Tabella per rappresentare la relazione Molti-1 fra i Racconti e le origini.' ");
sb.AppendLine(" [IDlnk] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del link fra Racconti-Origini' ");
sb.AppendLine(" [IDrac] INTEGER NOT NULL, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [IDori] INTEGER NOT NULL, -- COMMENT 'Identificativo dell'' origine' ");
sb.AppendLine(" UNIQUE(IDrac, IDori), ");
sb.AppendLine(" FOREIGN KEY(`IDrac`) REFERENCES `Racconti`(`IDrac`) ON DELETE CASCADE ON UPDATE CASCADE, ");
sb.AppendLine(" FOREIGN KEY(`IDori`) REFERENCES `Origini`(`IDori`) ON DELETE CASCADE ON UPDATE CASCADE ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Links_Rac_Vot] ( -- COMMENT 'Tabella per rappresentare la relazione Molti-1 fra i Racconti e i voti.' ");
sb.AppendLine(" [IDlnk] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del link fra Racconti-Voti' ");
sb.AppendLine(" [IDrac] INTEGER NOT NULL, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [IDvot] INTEGER NOT NULL, -- COMMENT 'Identificativo del voto' ");
sb.AppendLine(" UNIQUE(IDrac), ");
sb.AppendLine(" FOREIGN KEY(`IDrac`) REFERENCES `Racconti`(`IDrac`) ON DELETE CASCADE ON UPDATE CASCADE, ");
sb.AppendLine(" FOREIGN KEY(`IDvot`) REFERENCES `Voti`(`IDvot`) ON DELETE CASCADE ON UPDATE CASCADE ");
sb.AppendLine(" ); ");
sb.AppendLine(" CREATE TABLE [Links_Rac_Sng] ( -- COMMENT 'Tabella per rappresentare la relazione 1-Molti fra i Racconti e i segnalini.' ");
sb.AppendLine(" [IDlnk] INTEGER PRIMARY KEY, -- COMMENT 'Identificativo del link fra Racconti-Segnalini' ");
sb.AppendLine(" [IDrac] INTEGER NOT NULL, -- COMMENT 'Identificativo del racconto' ");
sb.AppendLine(" [IDsng] INTEGER NOT NULL, -- COMMENT 'Identificativo del segnalino' ");
sb.AppendLine(" UNIQUE(IDsng), ");
sb.AppendLine(" FOREIGN KEY(`IDrac`) REFERENCES `Racconti`(`IDrac`) ON DELETE CASCADE ON UPDATE CASCADE, ");
sb.AppendLine(" FOREIGN KEY(`IDsng`) REFERENCES `Segnalini`(`IDsng`) ON DELETE CASCADE ON UPDATE CASCADE ");
sb.AppendLine(" ); ");
sb.AppendLine(" -- ");
sb.AppendLine(" -- Creazione degli indici: ");
sb.AppendLine(" -- ");
sb.AppendLine(" CREATE INDEX IDX_Voti ON Voti ( Voto COLLATE NOCASE ); ");
if (FixedData) {
sb.AppendLine(" -- ");
sb.AppendLine(" -- Inserimento dei dati iniziali noti: ");
sb.AppendLine(" -- ");
sb.AppendLine(" INSERT INTO `origini` (`IDori`, `Origine`) VALUES ");
sb.AppendLine(" (1, 'Unknown'), ");
sb.AppendLine(" (2, 'Autocreazione'), ");
sb.AppendLine(" (3, 'A69'), ");
sb.AppendLine(" (4, 'eRac'), ");
sb.AppendLine(" (5, 'Mil'); ");
sb.AppendLine(" INSERT INTO `users` (`IDusr`, `Username`, `Password`, `Level`) VALUES ");
sb.AppendLine(" (1, 'root', 'e10adc3949ba59abbe56e057f20f883e', 9), ");
sb.AppendLine(" (2, 'Mrk', 'ABC', 8), ");
sb.AppendLine(" (3, 'reader', 'A', 5), ");
sb.AppendLine(" (4, 'guest', 'A', 0); ");
sb.AppendLine(" INSERT INTO `voti` (`IDvot`, `Rating`, `Voto`) VALUES ");
sb.AppendLine(" (0, 0, 'Non Letto'), ");
sb.AppendLine(" (1, 1, 'Da Cancellare'), ");
sb.AppendLine(" (2, 2, 'Pessimo'), ");
sb.AppendLine(" (3, 3, 'Brutto'), ");
sb.AppendLine(" (4, 4, 'Scarso'), ");
sb.AppendLine(" (5, 5, 'Insufficiente'), ");
sb.AppendLine(" (6, 6, 'Sufficiente'), ");
sb.AppendLine(" (7, 7, 'Carino'), ");
sb.AppendLine(" (8, 8, 'Bello'), ");
sb.AppendLine(" (9, 9, 'Ottimo'), ");
sb.AppendLine(" (10, 10, 'Da Collezione'); ");
}
sb.AppendLine(" -- ");
sb.AppendLine(" -- Creazione dei trigger: ");
sb.AppendLine(" -- ");
sb.AppendLine(" --- Triggers sulla tabella Racconti: --- ");
sb.AppendLine(" CREATE TRIGGER TRG_Racconti_Delete ");
sb.AppendLine(" AFTER DELETE ON Racconti ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" ");
sb.AppendLine(" DELETE FROM Links_Rac_Aut WHERE IDrac=OLD.IDrac; ");
sb.AppendLine(" DELETE FROM Links_Rac_Ori WHERE IDrac=OLD.IDrac; ");
sb.AppendLine(" DELETE FROM Links_Rac_Tag WHERE IDrac=OLD.IDrac; ");
sb.AppendLine(" DELETE FROM Links_Rac_Not WHERE IDrac=OLD.IDrac; ");
sb.AppendLine(" DELETE FROM Links_Rac_Vot WHERE IDrac=OLD.IDrac; ");
sb.AppendLine(" DELETE FROM Links_Rac_Sng WHERE IDrac=OLD.IDrac; ");
sb.AppendLine(" DELETE FROM Trame WHERE IDrac=OLD.IDrac; ");
sb.AppendLine(" DELETE FROM Notes WHERE IDnot NOT IN(SELECT Notes.IDnot FROM Notes, Links_Rac_not WHERE Notes.IDnot = Links_Rac_Not.IDnot); ");
sb.AppendLine(" DELETE FROM Segnalini WHERE IDsng NOT IN(SELECT Segnalini.IDsng FROM Segnalini, Links_Rac_Sng WHERE Segnalini.IDsng = Links_Rac_Sng.IDsng); ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Racconti_Insert ... END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Racconti_Update ... END; ");
sb.AppendLine(" --- Triggers sulla tabella Autori: --- ");
sb.AppendLine(" CREATE TRIGGER TRG_Autori_Delete ");
sb.AppendLine(" BEFORE DELETE ON Autori ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT COUNT(IDlnk) FROM Links_Rac_Aut WHERE IDaut=OLD.IDaut) > 0 ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Autore ancora riferito a dei racconti.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Autori_Insert ... END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Autori_Update ... END; ");
sb.AppendLine(" --- Triggers sulla tabella Origini: --- ");
sb.AppendLine(" CREATE TRIGGER TRG_Origini_Delete ");
sb.AppendLine(" BEFORE DELETE ON Origini ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT COUNT(IDlnk) FROM Links_Rac_Ori WHERE IDori=OLD.IDori) > 0 ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Origine ancora riferita a dei racconti.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Origini_Insert_Origine ... END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Origini_Update_Origine ... END; ");
sb.AppendLine(" --- Triggers sulla tabella Tags: --- ");
sb.AppendLine(" CREATE TRIGGER TRG_Tags_Delete ");
sb.AppendLine(" BEFORE DELETE ON Tags ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT COUNT(IDlnk) FROM Links_Rac_Tag WHERE IDtag=OLD.IDtag) > 0 ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Propietà ancora riferita a dei racconti.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Tags_Insert ... END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Tags_Update ... END; ");
sb.AppendLine(" --- Triggers sulla tabella Notes: --- ");
sb.AppendLine(" CREATE TRIGGER TRG_Notes_Delete ");
sb.AppendLine(" BEFORE DELETE ON Notes ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT COUNT(IDlnk) FROM Links_Rac_Not WHERE IDnot=OLD.IDnot) > 0 ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Nota ancora riferita a dei racconti.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Notes_Insert ... END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Notes_Update ... END; ");
sb.AppendLine(" --- Triggers sulla tabella Trame: --- ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Trama_Delete ... END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Trama_Insert ");
sb.AppendLine(" BEFORE INSERT ON Trame ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto associato alla trama non presente in ATDB.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Trama_Update_Trama ");
sb.AppendLine(" BEFORE UPDATE OF IDrac ON Trame ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto associato alla trama non presente in ATDB.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- Triggers sulla tabella Segnalini: --- ");
sb.AppendLine(" CREATE TRIGGER TRG_Segnalini_Delete ");
sb.AppendLine(" BEFORE DELETE ON Segnalini ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT COUNT(IDlnk) FROM Links_Rac_Sng WHERE IDsng=OLD.IDsng) > 0 ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Segnalino ancora riferito a dei racconti.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Segnalini_Insert ... END; ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Segnalini_Update ... END; ");
sb.AppendLine(" --- Triggers sulla tabella Links_Rac_Aut: --- ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Links_Rac_Aut_Delete ... END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Aut_Insert ");
sb.AppendLine(" BEFORE INSERT ON Links_Rac_Aut ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato all autore, non presente in ATDB.') ");
sb.AppendLine(" WHEN (SELECT IDaut from Autori WHERE IDaut=NEW.IDaut) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Autore, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Aut_Update_a ");
sb.AppendLine(" BEFORE UPDATE OF IDrac ON Links_Rac_Aut ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato all autore, non presente in ATDB.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Aut_Update_b ");
sb.AppendLine(" BEFORE UPDATE OF IDaut ON Links_Rac_Aut ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDaut from Autori WHERE IDaut=NEW.IDaut) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Autore, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- Triggers sulla tabella Links_Rac_Ori: --- ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Links_Rac_Ori_Delete ... END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Ori_Insert ");
sb.AppendLine(" BEFORE INSERT ON Links_Rac_Ori ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato all origine, non presente in ATDB.') ");
sb.AppendLine(" WHEN (SELECT IDori from Origini WHERE IDori=NEW.IDori) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Origine, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Ori_Update_a ");
sb.AppendLine(" BEFORE UPDATE OF IDrac ON Links_Rac_Ori ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato all origine, non presente in ATDB.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Ori_Update_b ");
sb.AppendLine(" BEFORE UPDATE OF IDori ON Links_Rac_Ori ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDori from Origini WHERE IDori=NEW.IDori) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Origine, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- Triggers sulla tabella Links_Rac_Tag: --- ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Links_Rac_Tag_Delete ... END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Tag_Insert ");
sb.AppendLine(" BEFORE INSERT ON Links_Rac_Tag ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato alla propietà, non presente in ATDB.') ");
sb.AppendLine(" WHEN (SELECT IDtag from Tags WHERE IDtag=NEW.IDtag) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Propietà, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Tag_Update_a ");
sb.AppendLine(" BEFORE UPDATE OF IDrac ON Links_Rac_Tag ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato alla propietà, non presente in ATDB.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Tag_Update_b ");
sb.AppendLine(" BEFORE UPDATE OF IDtag ON Links_Rac_Tag ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDtag from Tags WHERE IDtag=NEW.IDtag) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Propietà, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- Triggers sulla tabella Links_Rac_Not: --- ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Links_Rac_Not_Delete ... END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Not_Insert ");
sb.AppendLine(" BEFORE INSERT ON Links_Rac_Not ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato alla nota, non presente in ATDB.') ");
sb.AppendLine(" WHEN (SELECT IDnot from Notes WHERE IDnot=NEW.IDnot) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Nota, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Not_Update_a ");
sb.AppendLine(" BEFORE UPDATE OF IDrac ON Links_Rac_Not ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato alla nota, non presente in ATDB.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Not_Update_b ");
sb.AppendLine(" BEFORE UPDATE OF IDnot ON Links_Rac_Not ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDnot from Notes WHERE IDnot=NEW.IDnot) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Nota, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" --- Triggers sulla tabella Links_Rac_Sng: --- ");
sb.AppendLine(" --- CREATE TRIGGER TRG_Links_Rac_Sng_Delete ... END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Sng_Insert ");
sb.AppendLine(" BEFORE INSERT ON Links_Rac_Sng ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato al Segnalino, non presente in ATDB.') ");
sb.AppendLine(" WHEN (SELECT IDsng from Segnalini WHERE IDsng=NEW.IDsng) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Segnalino, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Sng_Update_a ");
sb.AppendLine(" BEFORE UPDATE OF IDrac ON Links_Rac_Sng ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDrac from Racconti WHERE IDrac=NEW.IDrac) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Racconto, associato all Segnalino, non presente in ATDB.') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE TRIGGER TRG_Links_Rac_Sng_Update_b ");
sb.AppendLine(" BEFORE UPDATE OF IDsng ON Links_Rac_Sng ");
sb.AppendLine(" BEGIN ");
sb.AppendLine(" SELECT CASE ");
sb.AppendLine(" WHEN (SELECT IDsng from Segnalini WHERE IDsng=NEW.IDsng) IS NULL ");
sb.AppendLine(" THEN RAISE(ABORT, 'Foreign key violation: Segnalino, da associare al racconto, non presente in ATDB') ");
sb.AppendLine(" END; ");
sb.AppendLine(" END; ");
sb.AppendLine(" CREATE VIEW Autore_Browser_Autori AS ");
sb.AppendLine(" SELECT ");
sb.AppendLine(" IDaut, ");
sb.AppendLine(" Autore, ");
sb.AppendLine(" ( ");
sb.AppendLine(" SELECT COUNT(IDaut) ");
sb.AppendLine(" FROM Links_Rac_Aut ");
sb.AppendLine(" WHERE Links_Rac_Aut.IDaut = Autori.IDaut ");
sb.AppendLine(" ) AS Num, ");
sb.AppendLine(" ( ");
sb.AppendLine(" SELECT AVG(Voti.IDvot) ");
sb.AppendLine(" FROM Links_Rac_Aut, ");
sb.AppendLine(" Links_Rac_Vot, ");
sb.AppendLine(" Voti ");
sb.AppendLine(" WHERE Links_Rac_Aut.IDaut = Autori.IDaut AND ");
sb.AppendLine(" Links_Rac_Vot.IDrac = Links_Rac_Aut.IDrac AND ");
sb.AppendLine(" Voti.IDvot = Links_Rac_Vot.IDvot AND ");
sb.AppendLine(" Voti.IDvot <> 0 ");
sb.AppendLine(" ) AS Rate ");
sb.AppendLine(" FROM Autori ");
sb.AppendLine(" ORDER BY Num DESC, Rate DESC; ");
sb.AppendLine(" -- ");
sb.AppendLine(" -- Inserimento delle viste: ");
sb.AppendLine(" -- ");
sb.AppendLine(" CREATE VIEW Tag_Browser_Tags AS ");
sb.AppendLine(" SELECT ");
sb.AppendLine(" IDtag, ");
sb.AppendLine(" Tag, ");
sb.AppendLine(" ( ");
sb.AppendLine(" SELECT COUNT(IDtag) ");
sb.AppendLine(" FROM Links_Rac_Tag ");
sb.AppendLine(" WHERE Links_Rac_Tag.IDtag = Tags.IDtag ");
sb.AppendLine(" ) AS Num, ");
sb.AppendLine(" ( ");
sb.AppendLine(" SELECT AVG(Voti.IDvot) ");
sb.AppendLine(" FROM Links_Rac_Tag, ");
sb.AppendLine(" Links_Rac_Vot, ");
sb.AppendLine(" Voti ");
sb.AppendLine(" WHERE Links_Rac_Tag.IDtag = Tags.IDtag AND ");
sb.AppendLine(" Links_Rac_Vot.IDrac = Links_Rac_Tag.IDrac AND ");
sb.AppendLine(" Voti.IDvot = Links_Rac_Vot.IDvot AND ");
sb.AppendLine(" Voti.IDvot <> 0 ");
sb.AppendLine(" ) AS Rate ");
sb.AppendLine(" FROM Tags ");
sb.AppendLine(" ORDER BY Num DESC, Rate DESC; ");
sb.AppendLine("-- ");
sb.AppendLine("-- ");
sb.AppendLine("------------------------------------------------------------------------------");
#endregion
return sb.ToString();
}
#endregion
/// <summary>
/// Ritorna lo stato di un link
/// </summary>
/// <param name="url">URL identificativo del link</param>
/// <returns>Stato del link nel DB (ToDownload se link non presente nel DB)</returns>
public eLinkState GetStateByURL(string url) {
lock (objLock) {
try {
System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand();
cmd.Connection = cn;
cmd.CommandText = "SELECT Status FROM LinksLog WHERE LinkURL=@LinkURL LIMIT 1";
cmd.CommandType = System.Data.CommandType.Text;
System.Data.SQLite.SQLiteParameter param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@LinkURL";
param.DbType = global::System.Data.DbType.String;
param.SourceColumn = "LinkURL";
cmd.Parameters.Add(param);
cmd.Parameters[0].Value = url;
object obj = cmd.ExecuteScalar();
if (obj != null) return (eLinkState)((long)obj);
return eLinkState.ToDownload;
} catch (Exception ex) {
Logger.Log(new object[] { "Error Code: DB06521", string.Format("MyDownloader.DBTools.GetStateByURL({0})", url), ex });
return eLinkState.Error;
}
}
}
/// <summary>
/// Verifica se il link è già presente nel DB
/// </summary>
/// <param name="url">URL del link da testare</param>
/// <param name="timeOffset">Offset temporale per la verifica (0 per l'intero DB)</param>
/// <returns>True se URL presente, false altrimenti</returns>
public bool IsPresent(string url, int timeOffset = 0) {
lock (objLock) {
try {
string query = timeOffset != 0 ?
"SELECT Status FROM LinksLog WHERE LinkURL=@LinkURL AND LastUpdate>=@LastUpdate LIMIT 1" :
"SELECT Status FROM LinksLog WHERE LinkURL=@LinkURL LIMIT 1" ;
System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand();
cmd.Connection = cn;
cmd.CommandText = query;
cmd.CommandType = System.Data.CommandType.Text;
System.Data.SQLite.SQLiteParameter param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@LinkURL";
param.DbType = global::System.Data.DbType.String;
param.SourceColumn = "LinkURL";
cmd.Parameters.Add(param);
param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@LastUpdate";
param.DbType = global::System.Data.DbType.DateTime;
param.SourceColumn = "LastUpdate";
cmd.Parameters.Add(param);
cmd.Parameters[0].Value = url;
cmd.Parameters[1].Value = DateTime.Now.AddHours(timeOffset);
object obj = cmd.ExecuteScalar();
if (obj != null) return true;
return false;
} catch (Exception ex) {
Logger.Log(new object[] { "Error Code: DB06521", string.Format("MyDownloader.DBTools.GetStateByURL({0})", url), ex });
return false;
}
}
}
/// <summary>
/// Aggiorna il log relativo al link nel DB.
/// </summary>
/// <returns>True se tutto ok; False altrimenti.</returns>
public bool LinkLog(iLink link) {
lock (objLock) {
return LinkLogUpdtate(link);
}
}
private bool LinkLogUpdtate(iLink link) {
// object obj = new Object();
// lock (obj) {
// Cancello riga (se non presente, non fa nulla)
// Inserisco riga
bool Res = false;
try {
// Cancello il link anche se non presente
System.Data.SQLite.SQLiteCommand cmd = new SQLiteCommand(string.Format("DELETE FROM [LinksLog] WHERE [LinkURL]='{0}'", link.URL), cn);
int res = cmd.ExecuteNonQuery();
cmd = null;
// Inserisco il link come se fosse nuovo
cmd = new System.Data.SQLite.SQLiteCommand();
cmd.Connection = cn;
cmd.CommandText = "INSERT INTO [LinksLog] VALUES(@LinkURL, @FileName, @PlugID, @Fields, @Status, @LastUpdate)";
cmd.CommandType = System.Data.CommandType.Text;
System.Data.SQLite.SQLiteParameter param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@LinkURL";
param.DbType = global::System.Data.DbType.String;
param.SourceColumn = "LinkURL";
cmd.Parameters.Add(param);
param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@FileName";
param.DbType = global::System.Data.DbType.String;
param.SourceColumn = "FileName";
cmd.Parameters.Add(param);
param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@PlugID";
param.DbType = global::System.Data.DbType.String;
param.SourceColumn = "PlugID";
cmd.Parameters.Add(param);
param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@Fields";
param.DbType = global::System.Data.DbType.String;
param.SourceColumn = "Fields";
cmd.Parameters.Add(param);
param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@Status";
param.DbType = global::System.Data.DbType.Int32;
param.SourceColumn = "Status";
cmd.Parameters.Add(param);
param = new System.Data.SQLite.SQLiteParameter();
param.ParameterName = "@LastUpdate";
param.DbType = global::System.Data.DbType.DateTime;
param.SourceColumn = "LastUpdate";
cmd.Parameters.Add(param);
cmd.Parameters[0].Value = link.URL;
cmd.Parameters[1].Value = link.FileName;
cmd.Parameters[2].Value = link.ID;
cmd.Parameters[3].Value = link.Fields;
cmd.Parameters[4].Value = link.Status;
cmd.Parameters[5].Value = DateTime.Now;
res = cmd.ExecuteNonQuery();
if (res != 1) {
Logger.Log(new object[] { "Error Code: DB06010", string.Format("MyDownloader.DBTools.LinkLogUpdtate({0})={1}", link, res), link.ToString() });
Res = false;
} else {
Res = true;
}
} catch (Exception ex) {
Logger.Log(new object[] { "Error Code: DB06001", string.Format("MyDownloader.DBTools.LinkLogUpdtate({0})", link), link.ToString(), ex });
return false;
} finally {
//if ((cn != null) && (cn.State != System.Data.ConnectionState.Closed)) cn.Close();
}
return Res;
// } // lock (obj)
}
} // class DBTools
}//namespace A69WD