using EFCDesk.Entidades; using System; using System.Collections.Generic; using System.ComponentModel.Design; using System.Data.Common; using System.Data.SQLite; using System.Drawing; using System.Drawing.Printing; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Runtime.InteropServices.JavaScript.JSType; using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar; namespace EFCDesk.Classes { public class SQLiteHelper { private string _connectionString; public SQLiteHelper(string databasePath) { _connectionString = $"Data Source={databasePath};Version=3;Journal Mode=WAL;Pooling=true;Cache Size=10000;Synchronous=OFF;"; InitializeDatabase(); } private void InitializeDatabase() { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); // Configuración para mejor concurrencia using (var pragmaCmd = new SQLiteCommand("PRAGMA busy_timeout = 30000;", connection)) { pragmaCmd.ExecuteNonQuery(); } string createConfiguracionTableQuery = @" CREATE TABLE IF NOT EXISTS Configuracion ( Id INTEGER PRIMARY KEY AUTOINCREMENT, IniciarExpedienteWindows INTEGER NOT NULL DEFAULT 0, FolderParaGenerarExpediente TEXT, DepurarExpediente INTEGER, FolderParaDepurarExpediente TEXT, UsarEstructuraPedimentosWinsaai INTEGER, UsarExpedienteLogistico INTEGER, ServidorFTP TEXT, UsuarioFTP TEXT, PasswordFTP TEXT, PuertoFTP INTEGER, ModoPasivoFTP INTEGER );"; string createArchivosProcesadosTableQuery = @" CREATE TABLE IF NOT EXISTS ArchivosProcesados ( IdArchivo INTEGER PRIMARY KEY AUTOINCREMENT, NombreArchivo TEXT NOT NULL, RutaArchivo TEXT NOT NULL UNIQUE, Estado TEXT NOT NULL DEFAULT 'Pendiente', FechaProcesado DATETIME DEFAULT NULL, FolderExpediente TEXT NOT NULL, CarpetaRaiz TEXT NOT NULL, HashContenido TEXT, -- opcional ArchivoZip TEXT NOT NULL );"; string createErrorLogTableQuery = @" CREATE TABLE IF NOT EXISTS ErrorLog ( Id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, LineaError TEXT, Clase TEXT, Metodo TEXT, Error TEXT, Comentario TEXT, Fecha TEXT );"; string createCarpetasTableQuery = @" CREATE TABLE IF NOT EXISTS Carpetas ( Id INTEGER PRIMARY KEY AUTOINCREMENT, Ruta TEXT NOT NULL UNIQUE, Nombre TEXT NOT NULL, Tipo TEXT NOT NULL, -- Hijo o Nieto Estado TEXT NOT NULL, -- Nuevo o Procesado FechaCreado DATETIME DEFAULT NULL, TaskId TEXT DEFAULT NULL );"; string createIndex = @" CREATE INDEX IF NOT EXISTS IX_Carpetas_Estado ON Carpetas(Estado); CREATE INDEX IF NOT EXISTS IX_Archivos_Ruta ON ArchivosProcesados(RutaArchivo); "; string pragmaModeQuery = "PRAGMA journal_mode=WAL;"; // Ejecutar las consultas para crear las tablas using (var command = new SQLiteCommand(connection)) { command.CommandText = createConfiguracionTableQuery; command.ExecuteNonQuery(); command.CommandText = createArchivosProcesadosTableQuery; command.ExecuteNonQuery(); command.CommandText = createErrorLogTableQuery; command.ExecuteNonQuery(); command.CommandText = createCarpetasTableQuery; command.ExecuteNonQuery(); command.CommandText = createIndex; command.ExecuteNonQuery(); command.CommandText = pragmaModeQuery; command.ExecuteNonQuery(); } } } catch (SQLiteException ex) { MessageBox.Show(ex.ToString()); } } public SQLiteConnection GetConnection() { return new SQLiteConnection(_connectionString); } private async Task GetOpenConnectionAsync(int maxRetries = 3) { int retryCount = 0; while (retryCount < maxRetries) { try { var connection = new SQLiteConnection(_connectionString); await connection.OpenAsync(); return connection; } catch (SQLiteException ex) when (ex.ResultCode == SQLiteErrorCode.Busy && retryCount < maxRetries - 1) { retryCount++; await Task.Delay(100 * retryCount); // Backoff exponencial } } throw new InvalidOperationException("No se pudo establecer conexión después de varios intentos"); } public List<(string ArchivoZip, string Estado)> ObtenerArchivosZIP() { var lista = new List<(string ArchivoZip, string Estado)>(); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string query = "SELECT DISTINCT ArchivoZip, Estado from ArchivosProcesados;"; using (var command = new SQLiteCommand(query, connection)) using (var reader = command.ExecuteReader()) { while (reader.Read()) { lista.Add(( reader.GetString(0), // CarpetaCliente reader.GetString(1) // CarpetaPedimento //reader.GetString(2) // NombreArchivo //reader.GetString(3) // FechaProcesado )); } } } return lista; } public List<(string Archivo, string Zip, DateTime Fecha, string Estado)> ObtenerArchivosProcesados(string archivoZIP) { var lista = new List<(string Archivo, string Zip, DateTime Fecha, string Estado)>(); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string query = "SELECT NombreArchivo, ArchivoZip, FechaProcesado, Estado FROM ArchivosProcesados WHERE ArchivoZip = @archivoZIP;"; using (var command = new SQLiteCommand(query, connection)) { // Agregar el parámetro con su valor command.Parameters.AddWithValue("@archivoZIP", archivoZIP); using (var reader = command.ExecuteReader()) { while (reader.Read()) { string nombreArchivo = reader.GetString(0); string archivoZip = reader.GetString(1); string Estatus = reader.GetString(3); DateTime fechaProcesado = DateTime.MinValue; // Valor por defecto if (!reader.IsDBNull(2)) { fechaProcesado = reader.GetDateTime(2); // Obtener como DateTime directamente } lista.Add((nombreArchivo, archivoZip, fechaProcesado, Estatus)); } } } } return lista; } public void RegistrarArchivoProcesado(string nombreArchivo, string rutaArchivo, string estado, DateTime fechaProcesado, string folderExpediente, string archivoZip) { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); // Verificar si el archivo ya existe en la tabla string checkQuery = @" SELECT COUNT(1) FROM ArchivosProcesados WHERE NombreArchivo = @NombreArchivo;"; using (var checkCommand = new SQLiteCommand(checkQuery, connection)) { checkCommand.Parameters.AddWithValue("@NombreArchivo", nombreArchivo); long count = (long)checkCommand.ExecuteScalar(); if (count > 0) { // Si ya existe, no hacer nada return; } } // Insertar el registro si no existe string insertQuery = @" INSERT INTO ArchivosProcesados (NombreArchivo, RutaArchivo, Estado, FechaProcesado, FolderExpediente, ArchivoZip) VALUES (@NombreArchivo, @RutaArchivo, @Estado, @FechaProcesado, @FolderExpediente, @Archivozip);"; using (var command = new SQLiteCommand(insertQuery, connection)) { command.Parameters.AddWithValue("@NombreArchivo", nombreArchivo); command.Parameters.AddWithValue("@RutaArchivo", rutaArchivo); command.Parameters.AddWithValue("@Estado", estado); command.Parameters.AddWithValue("@FechaProcesado", fechaProcesado); command.Parameters.AddWithValue("@FolderExpediente", folderExpediente); command.Parameters.AddWithValue("@Archivozip", archivoZip); command.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public void AgregarRegistroErrorLog(Exception ex, string sClase, string sMetodo, string sComentario = "") { string sLineaError = ""; try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); sLineaError = ex.StackTrace.ToString(); int last = sLineaError.LastIndexOf("\\"); sLineaError = sLineaError.Substring(last, sLineaError.Length - last).Replace("\\", ""); DateTime thisDayHour = DateTime.Now; string sFechaHora = thisDayHour.ToString("yyyyMMddHHmmss"); string sFecha = sFechaHora.Substring(0, 8); string insertQuery = @" INSERT INTO ErrorLog (LineaError, Clase, Metodo, Error, Comentario, Fecha) VALUES (@LineaError, @Clase, @Metodo, @Error, @Comentario, @Fecha);"; using (var command = new SQLiteCommand(insertQuery, connection)) { command.Parameters.AddWithValue("@LineaError", sLineaError); command.Parameters.AddWithValue("@Clase", sClase); command.Parameters.AddWithValue("@Metodo", sMetodo); command.Parameters.AddWithValue("@Error", ex.Message.ToString()); command.Parameters.AddWithValue("@Comentario", sComentario); command.Parameters.AddWithValue("@Fecha", sFechaHora); command.ExecuteNonQuery(); } } } catch (Exception e) { } } public List<(int id, string lineaError, string error, string comentarios, string fecha)> GetRegistrosErrorLog() { var lista = new List<(int id, string lineaError, string error, string comentarios, string fecha)>(); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string query = "SELECT Id, LineaError, Error, Comentario, Fecha FROM ErrorLog;"; using (var command = new SQLiteCommand(query, connection)) { using (var reader = command.ExecuteReader()) { while (reader.Read()) { int idLog = reader.GetInt32(0); lista.Add(( idLog, reader.IsDBNull(1) ? "" : reader.GetString(1), // ✅ Manejo de valores NULL reader.IsDBNull(2) ? "" : reader.GetString(2), reader.IsDBNull(3) ? "" : reader.GetString(3), reader.IsDBNull(4) ? "" : reader.GetString(4) )); } } } } return lista; } public bool ExisteConfiguracionExpediente() { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); // Verificar si hay registros en la tabla ArchivosProcesados string checkQuery = "SELECT COUNT(1) FROM Configuracion;"; int registrosExistentes; using (var command = new SQLiteCommand(checkQuery, connection)) { registrosExistentes = Convert.ToInt32(command.ExecuteScalar()); } // Si hay registros, no realizar el escaneo inicial if (registrosExistentes == 0) { return false; } } return true; } public List<(string Ruta, string Nombre, string Tipo)> ObtenerPendientes() { var lista = new List<(string, string, string)>(); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string query = "SELECT Ruta, Nombre, Tipo FROM Carpetas WHERE Estado IN('Nuevo','Pendiente')"; using (var command = new SQLiteCommand(query, connection)) { using (var reader = command.ExecuteReader()) { while (reader.Read()) { lista.Add((reader.GetString(0), reader.GetString(1), reader.GetString(2))); } } } } return lista; } public List<(string RutaArchivo, string NombreArchivo, string CarpetaRaiz, string ArchivoZip)> ObtenerArchivosPendientes() { var lista = new List<(string RutaArchivo, string NombreArchivo, string CarpetaRaiz, string ArchivoZip)>(); try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string sql = @" SELECT RutaArchivo, NombreArchivo, CarpetaRaiz, ArchivoZip FROM ArchivosProcesados WHERE Estado = 'Pendiente' ORDER BY CarpetaRaiz, ArchivoZip, NombreArchivo;"; using (var cmd = new SQLiteCommand(sql, connection)) using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { string ruta = reader.GetString(0); string nombre = reader.GetString(1); string carpetaRaiz = reader.GetString(2); string zip = reader.GetString(3); lista.Add((ruta, nombre, carpetaRaiz, zip)); } } } } catch (Exception ex) { Console.WriteLine($"Error al obtener archivos pendientes: {ex.Message}"); } return lista; } public List<(string ArchivoZip, string Estado, string fechaCreacion)> ObtenerCarpetas(string buscarRuta = "*") { var lista = new List<(string Nombre, string Estado, string fechaCreacion)>(); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string query = ""; if (buscarRuta == "*") { query = "SELECT Id, Nombre, Estado, FechaCreado from Carpetas ORDER BY FechaCreado DESC LIMIT 1000;"; } else { query = "SELECT Id, Nombre, Estado, FechaCreado from Carpetas WHERE Ruta=@RutaCarpeta LIMIT 1;"; } using (var command = new SQLiteCommand(query, connection)) { if (buscarRuta != "*") command.Parameters.AddWithValue("@RutaCarpeta", buscarRuta); using (var reader = command.ExecuteReader()) { while (reader.Read()) { lista.Add(( reader.GetString(1) + ".zip", // NombreCarpeta reader.GetString(2), // Estado reader.GetString(3) // Fecha Creacion )); } } } connection.Close(); } return lista; } public void UpsertCarpeta(string ruta, string nombre, string tipo, string estado) { try { string fecha = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); // Insertar el registro si no existe //string insertQuery = @" // INSERT INTO Carpetas (Ruta, Nombre, Tipo, Estado) // VALUES (@r, @n, @t, @e) // ON CONFLICT(Ruta) DO UPDATE SET // Tipo=excluded.Tipo, // Estado=excluded.Estado, // Nombre=excluded.Nombre; // "; string insertQuery = @" INSERT INTO Carpetas (Ruta, Nombre, Tipo, Estado, FechaCreado) VALUES (@r, @n, @t, @e, @f) ON CONFLICT(Ruta) DO NOTHING; "; using (var command = new SQLiteCommand(insertQuery, connection)) { command.Parameters.AddWithValue("@r", ruta); command.Parameters.AddWithValue("@n", nombre); command.Parameters.AddWithValue("@t", tipo); command.Parameters.AddWithValue("@e", estado); command.Parameters.AddWithValue("@f", fecha); command.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public void MarcarCarpetaProcesada(string expediente, string estado) { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string updateQuery = "UPDATE Carpetas SET Estado=@e WHERE Ruta=@r"; using (var command = new SQLiteCommand(updateQuery, connection)) { command.Parameters.AddWithValue("@r", expediente); command.Parameters.AddWithValue("@e", estado); command.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public bool GuardarTaskID(string rutaArchivo, string taskId) { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string updateQuery = "UPDATE Carpetas SET TaskId=@t WHERE Ruta=@r"; using (var command = new SQLiteCommand(updateQuery, connection)) { command.Parameters.AddWithValue("@r", rutaArchivo); command.Parameters.AddWithValue("@t", taskId); return command.ExecuteNonQuery() > 0; } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); return false; } } public void ActaulizarStatusCarpeta(string expediente, string estado) { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string updateQuery = "UPDATE Carpetas SET Estado=@e WHERE Ruta=@r OR Nombre=@r"; using (var command = new SQLiteCommand(updateQuery, connection)) { command.Parameters.AddWithValue("@r", expediente); command.Parameters.AddWithValue("@e", estado); command.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public bool EstaArchivoProcesado(string rutaArchivo) { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string updateQuery = "SELECT 1 FROM ArchivosProcesados WHERE RutaArchivo=@r AND Estado='Procesado' LIMIT 1"; using (var command = new SQLiteCommand(updateQuery, connection)) { command.Parameters.AddWithValue("@r", rutaArchivo); return command.ExecuteScalar() != null; } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); return false; } } public void RegistrarArchivoProcesado(string rutaArchivo, string nombreArchivo, string carpetaRaiz, string archivoZip, string? hashContenido) { try { string fecha = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); // Insertar el registro si no existe string insertQuery = @" INSERT OR IGNORE INTO ArchivosProcesados (RutaArchivo, NombreArchivo, CarpetaRaiz, HashContenido, ArchivoZip, FechaProcesado, FolderExpediente) VALUES (@r, @n, @cr, @h, @az, @f, @fe)"; using (var command = new SQLiteCommand(insertQuery, connection)) { command.Parameters.AddWithValue("@r", rutaArchivo); command.Parameters.AddWithValue("@n", nombreArchivo); command.Parameters.AddWithValue("@cr", carpetaRaiz); command.Parameters.AddWithValue("@h", (object?)hashContenido ?? DBNull.Value); command.Parameters.AddWithValue("@az", archivoZip); command.Parameters.AddWithValue("@f", fecha); command.Parameters.AddWithValue("@fe", ""); command.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public void MarcarArchivosZipComoProcesados(string archivoZip) { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string sql = @" UPDATE ArchivosProcesados SET Estado = 'Procesado', FechaProcesado = COALESCE(FechaProcesado, datetime('now')) WHERE ArchivoZip = @zip AND Estado <> 'Procesado';"; using (var cmd = new SQLiteCommand(sql, connection)) { // Ojo: si guardas solo el nombre (ej. "Carpeta1.zip"), // pásalo igual aquí. Si guardas ruta completa, pasa la ruta completa. cmd.Parameters.AddWithValue("@zip", archivoZip); cmd.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public void ActualizarEstadoArchivo(string rutaArchivo, string nuevoEstado) { try { string fecha = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string sql = @" UPDATE ArchivosProcesados SET Estado = @estado, FechaProcesado = COALESCE(@fecha, FechaProcesado) WHERE RutaArchivo = @ruta;"; using (var cmd = new SQLiteCommand(sql, connection)) { cmd.Parameters.AddWithValue("@estado", nuevoEstado); cmd.Parameters.AddWithValue("@ruta", rutaArchivo); cmd.Parameters.AddWithValue("@fecha", fecha); cmd.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public void LimpiarRegistrosInexistentes() { try { int archivosEliminados = 0; int carpetasEliminados = 0; // Eliminar los registros inexistentes de archivos using (var conn = new SQLiteConnection(_connectionString)) { conn.Open(); // Obtener todos los registros guardados using (var cmd = new SQLiteCommand("SELECT RutaArchivo FROM ArchivosProcesados", conn)) using (var reader = cmd.ExecuteReader()) { var rutasAEliminar = new List(); while (reader.Read()) { string ruta = reader.GetString(0); // Si el archivo ya no existe, lo marcamos para borrar del registro if (!File.Exists(ruta)) rutasAEliminar.Add(ruta); } reader.Close(); // Borrar registros inexistentes foreach (var ruta in rutasAEliminar) { using (var deleteCmd = new SQLiteCommand("DELETE FROM ArchivosProcesados WHERE RutaArchivo = @ruta", conn)) { deleteCmd.Parameters.AddWithValue("@ruta", ruta); archivosEliminados += deleteCmd.ExecuteNonQuery(); } } } conn.Close(); } // Eliminar los registros inexistentes de carpetas using (var conn = new SQLiteConnection(_connectionString)) { conn.Open(); // Obtener todos los registros guardados using (var cmd = new SQLiteCommand("SELECT Ruta FROM Carpetas", conn)) using (var reader = cmd.ExecuteReader()) { var rutasAEliminar = new List(); while (reader.Read()) { string ruta = reader.GetString(0); // Si el archivo ya no existe, lo marcamos para borrar del registro if (!Directory.Exists(ruta)) rutasAEliminar.Add(ruta); } reader.Close(); // Borrar registros inexistentes foreach (var ruta in rutasAEliminar) { using (var deleteCmd = new SQLiteCommand("DELETE FROM Carpetas WHERE Ruta = @ruta", conn)) { deleteCmd.Parameters.AddWithValue("@ruta", ruta); carpetasEliminados += deleteCmd.ExecuteNonQuery(); } } } conn.Close(); } Console.WriteLine($"Limpieza completada: {carpetasEliminados} registros eliminados de CarpetasProcesados."); Console.WriteLine($"Limpieza completada: {archivosEliminados} registros eliminados de ArchivosProcesados."); } catch (Exception ex) { Console.WriteLine($"Error en limpieza de registros inexistentes: {ex.Message}"); } } public bool ArchivoExiste(string rutaArchivo) { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string sql = @"SELECT COUNT(*) FROM ArchivosPendientes WHERE RutaArchivo = @Ruta"; using (var cmd = new SQLiteCommand(sql, connection)) { cmd.Parameters.AddWithValue("@Ruta", rutaArchivo); return Convert.ToInt32(cmd.ExecuteScalar()) > 0; } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); return false; } } public void GuardarArchivoPendiente(string rutaArchivo, string nombreArchivo, string carpetaRaiz, string archivoZip, string? hashContenido) { try { string fecha = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); // Insertar el registro si no existe string insertQuery = @" INSERT OR IGNORE INTO ArchivosProcesados (RutaArchivo, NombreArchivo, CarpetaRaiz, HashContenido, ArchivoZip, FechaProcesado, FolderExpediente, Estado) VALUES (@r, @n, @cr, @h, @az, @f, @fe, 'Pendiente')"; using (var command = new SQLiteCommand(insertQuery, connection)) { command.Parameters.AddWithValue("@r", rutaArchivo); command.Parameters.AddWithValue("@n", nombreArchivo); command.Parameters.AddWithValue("@cr", carpetaRaiz); command.Parameters.AddWithValue("@h", (object?)hashContenido ?? DBNull.Value); command.Parameters.AddWithValue("@az", archivoZip); command.Parameters.AddWithValue("@f", fecha); command.Parameters.AddWithValue("@fe", ""); command.ExecuteNonQuery(); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } public List ObtenerExpedientes(long pagina, long tamanioPagina = 1000, string buscarExpediente = "*") { long pageNumber = pagina; // pedimos la segunda página long pageSize = tamanioPagina; var lista = new List(); long offset = (pageNumber - 1) * pageSize; using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string query = ""; if (buscarExpediente == "*") { query = "SELECT Id, Nombre, Estado, FechaCreado, Ruta, TaskId from Carpetas ORDER BY Nombre DESC LIMIT @pageSize OFFSET @offset;"; } else { query = "SELECT Id, Nombre, Estado, FechaCreado, Ruta, TaskId from Carpetas WHERE Nombre LIKE '%' || @Expediente || '%' LIMIT @pageSize OFFSET @offset;"; } using (var command = new SQLiteCommand(query, connection)) { if (buscarExpediente != "*") command.Parameters.AddWithValue("@Expediente", buscarExpediente); command.Parameters.AddWithValue("@pageSize", pageSize); command.Parameters.AddWithValue("@offset", offset); using (var reader = command.ExecuteReader()) { while (reader.Read()) { var exp = new ExpedienteInfo { Expediente = reader.GetString(1), Estado = reader.GetString(2), FechaCreacion = reader.GetString(3), Ruta = reader.GetString(4), TaskId = reader.IsDBNull(5) ? "" : reader.GetString(5) }; lista.Add(exp); } } } connection.Close(); } return lista; } public async Task TotalExpedientes(string buscarExpediente = "*") { try { using (var connection = new SQLiteConnection(_connectionString)) { connection.Open(); string updateQuery = ""; if (buscarExpediente == "*") { updateQuery = "SELECT COUNT(*) AS Total FROM Carpetas;"; } else { updateQuery = "SELECT COUNT(*) AS Total FROM Carpetas WHERE Nombre LIKE '%' || @Expediente || '%';"; } using (var command = new SQLiteCommand(updateQuery, connection)) { if (buscarExpediente != "*") command.Parameters.AddWithValue("@Expediente", buscarExpediente); var result = await command.ExecuteScalarAsync(); return result == null ? 0 : Convert.ToInt64(result); } } } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); return 0; } } //public void Dispose() //{ // _conn?.Dispose(); // _conn = null; //} } }