Files
A69WD/Src/A69WD/Data/Helper.cs
T
CSiCoAlm 1fd91b4af2 Inserito Reader
Esempio base di lettore, con solo funzionalità di lettura random o sequenziale (frecce su/giu).
Testato e la lettura è corretta.

ToDo:
- [X] Inserire un lettore per visualizzare i racconti nel DB
- [ ] Inserire funzionalità avanzate di lettura (navigazione, filtri, ecc...)
- [0/2] Integrare lo scraping dei racconti dal web
   - [ ] Integrare lo scraping visualizzandolo sulla progress bar e label nella status bar.
   - [ ] Importare i racconti via via che sono downloadati
2025-12-29 11:48:05 +01:00

144 lines
6.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SQLite;
namespace A69WD.Data {
/*
*
* Questo file contiene i metodi statici per gestire le tabelle di lookup e i collegamenti.
* Nota che questi metodi accettano SqliteTransaction per operare all'interno del contesto della transazione principale.
*
* Vantaggi di questa suddivisione:
* - Helper statico: Non serve istanziare nulla per usare le funzioni di utilità.
* - Manutenibilità: Se cambi il modo in cui cerchi un autore, lo cambi in un solo punto (Helper.cs).
* - Transazioni pulite: DBTools.cs si occupa solo di aprire la transazione e chiamare in ordine i "mattoncini" forniti dall'Helper.
*
*/
public static class Helper {
// Ottiene ID o crea nuovo record per Autori, Tags, Origini
public static long GetOrCreateId(SQLiteConnection conn, SQLiteTransaction trans, string table, string colName, string idCol, string value) {
var cmdSelect = new SQLiteCommand($"SELECT {idCol} FROM {table} WHERE {colName} = @v", conn, trans);
cmdSelect.Parameters.AddWithValue("@v", value);
var result = cmdSelect.ExecuteScalar();
if (result != null) return (long)result;
var cmdInsert = new SQLiteCommand($"INSERT INTO {table} ({colName}) VALUES (@v); SELECT last_insert_rowid();", conn, trans);
cmdInsert.Parameters.AddWithValue("@v", value);
return (long)cmdInsert.ExecuteScalar();
}
// Helper specifico per le Note (Key-Value)
public static long GetOrCreateNoteId(SQLiteConnection conn, SQLiteTransaction trans, string key, string val) {
var cmdSelect = new SQLiteCommand("SELECT IDnot FROM Notes WHERE NKey = @k AND NVal = @v", conn, trans);
cmdSelect.Parameters.AddWithValue("@k", key);
cmdSelect.Parameters.AddWithValue("@v", val);
var result = cmdSelect.ExecuteScalar();
if (result != null) return (long)result;
var cmdInsert = new SQLiteCommand("INSERT INTO Notes (NKey, NVal) VALUES (@k, @v); SELECT last_insert_rowid();", conn, trans);
cmdInsert.Parameters.AddWithValue("@k", key);
cmdInsert.Parameters.AddWithValue("@v", val);
return (long)cmdInsert.ExecuteScalar();
}
// Crea il legame nelle tabelle Links_...
public static void ExecuteLink(SQLiteConnection conn, SQLiteTransaction trans, string table, string targetIdCol, long idRac, long targetId) {
var cmd = new SQLiteCommand($"INSERT OR IGNORE INTO {table} (IDrac, {targetIdCol}) VALUES (@r, @t)", conn, trans);
cmd.Parameters.AddWithValue("@r", idRac);
cmd.Parameters.AddWithValue("@t", targetId);
cmd.ExecuteNonQuery();
}
// Helper per la lettura rapida di liste di stringhe
public static List<string> GetList(SQLiteConnection conn, string sql, long IDrac) {
var list = new List<string>();
using (var cmd = new SQLiteCommand(sql, conn)) {
cmd.Parameters.AddWithValue("@IDrac", IDrac);
using (var reader = cmd.ExecuteReader()) {
while (reader.Read()) list.Add(reader.GetValue(0).ToString());
}
}
return list;
}
/// <summary>
/// Esegue una query che ritorna un scalare
/// </summary>
/// <param name="query">Query da eseguire sul DB</param>
/// <returns>Scalare ritornato dalla query</returns>
public static long ExecuteScalar(SQLiteConnection conn, string query, object objLock) {
lock (objLock) {
try {
// Eseguo il comando
System.Data.SQLite.SQLiteCommand cm = new SQLiteCommand(query, conn);
long res = (long)cm.ExecuteScalar(System.Data.CommandBehavior.SingleResult);
return res;
} catch (Exception ex) {
if (ex.Message == "Object reference not set to an instance of an object.") {
// nessun record trovato che soddisfi la query
return 0;
} else {
Logger.Error(string.Format("Error Code: {0} - Errore in {1}.{2}: {3}", "ER00100", System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.FullName, System.Reflection.MethodInfo.GetCurrentMethod().Name, ex.Message));
return -1;
}
}
}
} // ExecuteScalar
/// <summary>
/// Conteggia il numero di record nella colonna indicata contenuti nella tabella indicata.
/// </summary>
/// <param name="conn">Connessione al DB</param>
/// <param name="tableName">Nome della tabella in cui fare la query</param>
/// <param name="columName">Nome del campo da contare</param>
/// <param name="objLock">Oggetto per il lock fra i thread</param>
/// <returns>Il numero di record trovati, oppure un codice negativo in caso di errore.</returns>
public static long CountSimpleRecord(SQLiteConnection conn, string tableName, string columName, object objLock) {
// Ricreo la query:
string query = $"SELECT count(Distinct {tableName}.{columName}) AS NUM FROM {tableName}";
lock (objLock) {
try {
// Eseguo il comando
System.Data.SQLite.SQLiteCommand cm = new SQLiteCommand(query, conn);
long res = (long)cm.ExecuteScalar(System.Data.CommandBehavior.SingleResult);
return res;
} catch (Exception ex) {
if (ex.Message == "Object reference not set to an instance of an object.") {
// nessun record trovato che soddisfi la query
return 0;
} else {
Logger.Error(string.Format("Error Code: {0} - Errore in {1}.{2}: {3}", "ER00100", System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.FullName, System.Reflection.MethodInfo.GetCurrentMethod().Name, ex.Message));
return -1;
}
}
}
}//CountSimpleRecord
}//class Helper
public enum SaveResult {
Success = 0,
DatabaseConnectionError = 1,
MainRecordInsertError = 2,
TramaInsertError = 3,
RelationInsertError = 4,
SegnaliniInsertError = 5,
GenericError = 99
}
}//namespace A69WD.Data