using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Dapper; using Microsoft.Data.Sqlite; using Serilog; using SharpRss.Models; namespace SharpRss.Services { public class DatabaseService : IDisposable { private string _connectionString => $"Data Source={Path.Combine(Environment.CurrentDirectory, "sharp_rss.db")};"; internal DatabaseService() { _sqlConn = new SqliteConnection(_connectionString); InitializeDb(); } private readonly SqliteConnection _sqlConn; public async Task AddCategoriesAsync(HashSet categories) { bool result = true; _sqlConn.Open(); /*var queryResult = await _sqlConn.QueryAsync("SELECT * FROM category_data WHERE name=@catName", new { catName = category.Name }); var enumerable = queryResult.ToList(); if (queryResult != null && enumerable.Any()) // Category already exists! result = false;*/ foreach (var categoryModel in categories) { await _sqlConn.QueryAsync("INSERT OR IGNORE INTO category_data (name, hex_color, category_id) VALUES(@catName, @hexColor, @categoryId)", new { catName = categoryModel.Name, hexColor = categoryModel.HexColor, categoryId = categoryModel.CategoryId }); } /*if (result) { if (createResult.Any()) // Did not create the category result = false; }*/ _sqlConn.Close(); return result; } public async Task AddFeedsAsync(HashSet feeds) { bool result = true; _sqlConn.Open(); foreach (var feedModel in feeds) { await _sqlConn.QueryAsync("INSERT OR IGNORE INTO feed_data(url, feed_id, category_id) VALUES(@url, @feedId, @categoryId)", new { url = feedModel.Url, feedId = feedModel.FeedId, categoryId = feedModel.CategoryId }); } _sqlConn.Close(); return result; } public async Task> GetCategoriesAsync() { HashSet categories = new HashSet(); _sqlConn.Open(); SqliteCommand cmd = _sqlConn.CreateCommand(); cmd.CommandText = "SELECT * FROM category_data"; await using SqliteDataReader reader = await cmd.ExecuteReaderAsync(); while (reader.Read()) categories.Add(CategoryModel.Create(reader["name"].ToString(), reader["hex_color"].ToString(), reader["category_id"].ToString())); _sqlConn.Close(); return categories; } public async Task> GetFeedsAsync(string? categoryId = null) { HashSet feeds = new HashSet(); _sqlConn.Open(); SqliteCommand cmd = _sqlConn.CreateCommand(); cmd.CommandText = categoryId == null ? "SELECT * FROM feed_data" : "SELECT * FROM feed_data WHERE category_id=@categoryId"; if (categoryId != null) cmd.Parameters.Add(new SqliteParameter("categoryId", categoryId)); await using SqliteDataReader reader = await cmd.ExecuteReaderAsync(); while (reader.Read()) feeds.Add(FeedModel.Create(reader["url"].ToString(), reader["feed_id"].ToString(), reader["category_id"].ToString())); _sqlConn.Close(); return feeds; } private async void InitializeDb() { Log.Verbose("Checking database..."); _sqlConn.Open(); var queryResponse = await _sqlConn.QueryAsync("CREATE TABLE IF NOT EXISTS category_data (name STRING NOT NULL, hex_color STRING NOT NULL, category_id STRING PRIMARY KEY)"); if (queryResponse.Any()) { _sqlConn.Close(); _sqlConn.Dispose(); throw new SqliteException("Error initializing database!", 0); } queryResponse = await _sqlConn.QueryAsync("CREATE TABLE IF NOT EXISTS feed_data (url STRING NOT NULL, feed_id STRING PRIMARY KEY, category_id STRING DEFAULT '')"); if (queryResponse.Any()) { _sqlConn.Close(); _sqlConn.Dispose(); throw new SqliteException("Error initializing database!", 0); } _sqlConn.Close(); Log.Verbose("Checking database done!"); } public void Dispose() { _sqlConn.Dispose(); } } }