mirror of
https://github.com/hmaxnl/SharpRSS.git
synced 2024-09-20 01:54:20 +02:00
176 lines
7.6 KiB
C#
176 lines
7.6 KiB
C#
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
|
|
{
|
|
internal class DatabaseService : IDisposable
|
|
{
|
|
internal DatabaseService()
|
|
{
|
|
_sqlConn = new SqliteConnection(_connectionString);
|
|
InitializeDb();
|
|
}
|
|
private readonly SqliteConnection _sqlConn;
|
|
private readonly string _connectionString = $"Data Source={Path.Combine(Environment.CurrentDirectory, "sharp_rss.sqlite")};";
|
|
private readonly string _groupTable = "group_data";
|
|
private readonly string _feedTable = "feed_data";
|
|
private readonly string _feedItemTable = "feed_item_data";
|
|
|
|
// Group
|
|
public async Task<HashSet<GroupModel?>> GetGroupsAsync(string? groupName = null)
|
|
{
|
|
_sqlConn.Open();
|
|
SqliteCommand cmd = new SqliteCommand(groupName != null ? $"SELECT * FROM {_groupTable} WHERE name=@name;" : $"SELECT * FROM {_groupTable}", _sqlConn)
|
|
{
|
|
Parameters =
|
|
{
|
|
new SqliteParameter("name", groupName)
|
|
}
|
|
};
|
|
await using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
|
|
HashSet<GroupModel?> groups = new HashSet<GroupModel?>();
|
|
while (reader.Read())
|
|
{
|
|
groups.Add(new GroupModel()
|
|
{
|
|
Name = reader["name"].ToString(),
|
|
HexColor = reader["hex_color"].ToString(),
|
|
Icon = reader["icon"].ToString(),
|
|
Id = reader["id"].ToString()
|
|
});
|
|
}
|
|
_sqlConn.Close();
|
|
return groups;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a group if not exists else will update the group.
|
|
/// </summary>
|
|
/// <param name="groupModel"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> SetGroupAsync(GroupModel groupModel)
|
|
{
|
|
bool result = false;
|
|
_sqlConn.Open();
|
|
SqliteCommand cmd = new SqliteCommand($"INSERT OR REPLACE INTO {_groupTable} (id, hex_color, icon, name) VALUES (IFNULL((SELECT id FROM {_groupTable} WHERE name=@name), @id), @hexColor, @icon, @name)", _sqlConn)
|
|
{
|
|
Parameters =
|
|
{
|
|
new SqliteParameter("id", groupModel.Id),
|
|
new SqliteParameter("hexColor", groupModel.HexColor),
|
|
new SqliteParameter("icon", groupModel.Icon),
|
|
new SqliteParameter("name", groupModel.Name)
|
|
}
|
|
};
|
|
int affected = await cmd.ExecuteNonQueryAsync();
|
|
if (affected != 0)
|
|
result = true;
|
|
_sqlConn.Close();
|
|
return result;
|
|
}
|
|
|
|
public async Task<bool> RemoveGroupAsync(GroupModel groupModel)
|
|
{
|
|
bool result = false;
|
|
_sqlConn.Open();
|
|
// Remove the group and remove the feeds that were part of the group.
|
|
SqliteCommand cmd = new SqliteCommand($"DELETE FROM {_groupTable} WHERE id=@id; UPDATE {_feedTable} SET group_id=NULL WHERE group_id=@id", _sqlConn)
|
|
{
|
|
Parameters =
|
|
{
|
|
new SqliteParameter("id", groupModel.Id)
|
|
}
|
|
};
|
|
int affected = await cmd.ExecuteNonQueryAsync();
|
|
if (affected != 0)
|
|
result = true;
|
|
_sqlConn.Close();
|
|
return result;
|
|
}
|
|
// Feed
|
|
public async Task<HashSet<FeedModel>> GetFeedsAsync(string? feedName = null)
|
|
{
|
|
HashSet<FeedModel> feeds = new HashSet<FeedModel>();
|
|
_sqlConn.Open();
|
|
SqliteCommand cmd = new SqliteCommand(feedName != null ? $"SELECT * FROM {_feedTable} WHERE name=@name" : $"SELECT * FROM {_feedTable}", _sqlConn)
|
|
{
|
|
Parameters =
|
|
{
|
|
new SqliteParameter("name", feedName)
|
|
}
|
|
};
|
|
int affected = await cmd.ExecuteNonQueryAsync();
|
|
Log.Verbose("{FeedAmount} feeds found!", affected);
|
|
_sqlConn.Close();
|
|
return feeds;
|
|
}
|
|
|
|
public async Task<bool> AddFeedAsync(FeedModel feedModel)
|
|
{
|
|
bool result = false;
|
|
_sqlConn.Open();
|
|
SqliteCommand cmd = new SqliteCommand($"INSERT OR REPLACE INTO {_feedTable} (id, url, group_id, feed_type, description, language, copyright, date_added, last_updated, image_url)" +
|
|
$"VALUES (IFNULL((SELECT id FROM {_feedTable} WHERE url=@url), @id), @url, @groupId, @feedType, @description, @language, @copyright, @dateAdded, @lastUpdated, @imageUrl)", _sqlConn)
|
|
{
|
|
Parameters =
|
|
{
|
|
new SqliteParameter("id", feedModel.Id),
|
|
new SqliteParameter("url", feedModel.Url),
|
|
new SqliteParameter("groupId", feedModel.GroupId),
|
|
new SqliteParameter("feedType", feedModel.FeedType),
|
|
new SqliteParameter("description", feedModel.Description),
|
|
new SqliteParameter("language", feedModel.Language),
|
|
new SqliteParameter("copyright", feedModel.Copyright),
|
|
new SqliteParameter("dateAdded", feedModel.DateAdded.ToUnixTimeMilliseconds()),
|
|
new SqliteParameter("lastUpdated", feedModel.LastUpdated.ToUnixTimeMilliseconds()),
|
|
new SqliteParameter("imageUrl", feedModel.ImageUrl)
|
|
}
|
|
};
|
|
int affected = await cmd.ExecuteNonQueryAsync();
|
|
if (affected != 0)
|
|
result = true;
|
|
_sqlConn.Close();
|
|
return result;
|
|
}
|
|
// Feed item
|
|
|
|
private async void InitializeDb()
|
|
{
|
|
Log.Verbose("Checking database...");
|
|
HashSet<string> failed = new HashSet<string>();
|
|
_sqlConn.Open();
|
|
Log.Verbose("Checking table: {Table}", _groupTable);
|
|
var queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_groupTable} (name STRING NOT NULL, hex_color STRING NOT NULL, icon STRING, id STRING PRIMARY KEY)");
|
|
if (queryResponse.Any()) failed.Add("category_data");
|
|
|
|
Log.Verbose("Checking table: {Table}", _feedTable);
|
|
queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_feedTable} (id STRING PRIMARY KEY, url STRING NOT NULL, group_id STRING DEFAULT NULL, feed_type STRING, description STRING, language STRING, copyright STRING, date_added INT, last_updated INT, image_url STRING)");
|
|
if (queryResponse.Any()) failed.Add("feed_data");
|
|
|
|
Log.Verbose("Checking table: {Table}", _feedItemTable);
|
|
queryResponse = await _sqlConn.QueryAsync($"CREATE TABLE IF NOT EXISTS {_feedItemTable} (id STRING PRIMARY KEY, feed_id STRING DEFAULT NULL, read INT, type STRING, title STRING, description STRING, link STRING, last_updated INT, publishing_date INT, author STRING, categories STRING, content STRING)");
|
|
if (queryResponse.Any()) failed.Add("feed_item_data");
|
|
|
|
_sqlConn.Close();
|
|
if (failed.Any())
|
|
{
|
|
var joined = string.Join(',', failed);
|
|
Log.Error("Failed to initialize table(s): {TableNames}", joined);
|
|
}
|
|
else
|
|
Log.Verbose("Checking database done!");
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_sqlConn.Dispose();
|
|
}
|
|
}
|
|
} |