Working on db access

This commit is contained in:
Max Holleman 2023-06-02 10:56:30 +02:00
parent 1f0e8840c1
commit 4ef3b58a20
6 changed files with 117 additions and 76 deletions

View File

@ -4,6 +4,7 @@ using System.Data;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Transactions;
using Argotic.Syndication; using Argotic.Syndication;
using Dapper; using Dapper;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
@ -125,18 +126,54 @@ namespace SharpRss
{ {
Parameters = { new SqliteParameter("Url", url) } Parameters = { new SqliteParameter("Url", url) }
}; };
try
{
await using SqliteDataReader reader = await cmd.ExecuteReaderAsync(); await using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
if (reader.Read()) if (reader.Read())
feed = await ReaderToFeedModel(reader); feed = await ReaderToFeedModel(reader);
}
catch (Exception ex)
{
Log.Error(ex, "Error while fetching feed from db.");
}
return feed; return feed;
} }
public static async Task<FeedModel?> SetFeedsAsync(IEnumerable<FeedModel> feedModels) public static async Task<FeedModel?> SetFeedAsync(FeedModel feedModel)
{ {
//TODO: Implement fetching system!!! FeedModel? feed = null;
FeedModel? resultModel = null;
await using SqliteConnection dbc = new SqliteConnection(ConnectionString); await using SqliteConnection dbc = new SqliteConnection(ConnectionString);
dbc.Open(); dbc.Open();
await using SqliteTransaction transaction = dbc.BeginTransaction(); await using SqliteCommand cmd = new SqliteCommand($"INSERT OR REPLACE INTO {FeedTable} (url, title, group_id, feed_type, description, language, copyright, date_added, last_updated, image_url, original_document) VALUES (@url, @title, @groupId, @feedType, @description, @language, @copyright, @dateAdded), @lastUpdated, @imageUrl, @originalDoc); SELECT * FROM {FeedTable} WHERE url=@url", dbc)
{
Parameters =
{
new SqliteParameter("url", feedModel.Url ?? string.Empty),
new SqliteParameter("title", feedModel.Title ?? string.Empty),
new SqliteParameter("groupId", feedModel.GroupId ?? string.Empty),
new SqliteParameter("feedType", feedModel.FeedType ?? string.Empty),
new SqliteParameter("description", feedModel.Description ?? string.Empty),
new SqliteParameter("language", feedModel.Language ?? string.Empty),
new SqliteParameter("copyright", feedModel.Copyright ?? string.Empty),
new SqliteParameter("dateAdded", feedModel.DateAdded?.ToUnixTimeMilliseconds()),
new SqliteParameter("lastUpdated", feedModel.LastUpdated?.ToUnixTimeMilliseconds()),
new SqliteParameter("imageUrl", feedModel.ImageUrl ?? string.Empty),
new SqliteParameter("originalDoc", feedModel.OriginalDocument ?? string.Empty)
}
};
try
{
await using SqliteDataReader reader = await cmd.ExecuteReaderAsync();
feed = await ReaderToFeedModel(reader);
}
catch (Exception ex)
{
Log.Error(ex, "Database error, adding feed model to database failed!");
return feed;
}
return feed;
/*await using SqliteTransaction transaction = dbc.BeginTransaction();
try
{
foreach (var feedModel in feedModels) foreach (var feedModel in feedModels)
{ {
//await using SqliteCommand cmd = new SqliteCommand($"INSERT OR REPLACE INTO {_feedTable} (id, url, title, group_id, feed_type, description, language, copyright, date_added, last_updated, image_url, original_document) VALUES (IFNULL((SELECT id FROM {_feedTable} WHERE url=@url), @id), @url, @title, @groupId, @feedType, @description, @language, @copyright, IFNULL((SELECT date_added FROM {_feedTable} WHERE id=@id), @dateAdded), @lastUpdated, @imageUrl, @originalDoc); SELECT * FROM {_feedTable} WHERE url=@url", dbc) //await using SqliteCommand cmd = new SqliteCommand($"INSERT OR REPLACE INTO {_feedTable} (id, url, title, group_id, feed_type, description, language, copyright, date_added, last_updated, image_url, original_document) VALUES (IFNULL((SELECT id FROM {_feedTable} WHERE url=@url), @id), @url, @title, @groupId, @feedType, @description, @language, @copyright, IFNULL((SELECT date_added FROM {_feedTable} WHERE id=@id), @dateAdded), @lastUpdated, @imageUrl, @originalDoc); SELECT * FROM {_feedTable} WHERE url=@url", dbc)
@ -162,8 +199,13 @@ namespace SharpRss
await cmd.ExecuteNonQueryAsync(); await cmd.ExecuteNonQueryAsync();
} }
await transaction.CommitAsync(); await transaction.CommitAsync();
await FetchFeedItemsAsync(feedModels.Select(x => x.Url).ToArray()); }
return resultModel; catch (Exception ex)
{
await transaction.RollbackAsync();
Log.Error(ex, "Error on inserting feeds to db.");
return false;
}*/
} }
public static async Task FetchFeedItemsAsync(string[]? feedUrls = null) public static async Task FetchFeedItemsAsync(string[]? feedUrls = null)
@ -188,8 +230,8 @@ namespace SharpRss
{ {
GenericSyndicationFeed syndication = new GenericSyndicationFeed(); GenericSyndicationFeed syndication = new GenericSyndicationFeed();
syndication.Load(dbFeed.OriginalDocument); syndication.Load(dbFeed.OriginalDocument);
//TODO: Get items and add to db
} }
//TODO: Rewrite some stuff...
} }
public static async Task<bool> RemoveFeedAsync(FeedModel feedModel) public static async Task<bool> RemoveFeedAsync(FeedModel feedModel)
@ -197,11 +239,11 @@ namespace SharpRss
bool result = false; bool result = false;
await using SqliteConnection dbc = new SqliteConnection(ConnectionString); await using SqliteConnection dbc = new SqliteConnection(ConnectionString);
dbc.Open(); dbc.Open();
await using SqliteCommand cmd = new SqliteCommand($"DELETE FROM {FeedTable} WHERE id=@id; UPDATE {FeedItemTable} SET feed_id=NULL WHERE feed_id=@id", dbc) await using SqliteCommand cmd = new SqliteCommand($"DELETE FROM {FeedTable} WHERE url=@Url; UPDATE {FeedItemTable} SET feed_id=NULL WHERE feed_id=@Url", dbc)
{ {
Parameters = Parameters =
{ {
new SqliteParameter("id", feedModel.Id) new SqliteParameter("Url", feedModel.Url)
} }
}; };
int affected = await cmd.ExecuteNonQueryAsync(); int affected = await cmd.ExecuteNonQueryAsync();
@ -326,9 +368,9 @@ namespace SharpRss
} }
private static async Task<FeedModel> ReaderToFeedModel(SqliteDataReader reader) private static async Task<FeedModel> ReaderToFeedModel(SqliteDataReader reader)
{ {
FeedModel fetchedFeed = new FeedModel(reader["url"].ToString()) FeedModel fetchedFeed = new FeedModel()
{ {
Id = reader["id"].ToString(), Url = reader["url"].ToString(),
Title = reader["title"].ToString(), Title = reader["title"].ToString(),
GroupId = reader["group_id"].ToString(), GroupId = reader["group_id"].ToString(),
FeedType = reader["feed_type"].ToString(), FeedType = reader["feed_type"].ToString(),
@ -340,11 +382,12 @@ namespace SharpRss
ImageUrl = reader["image_url"].ToString(), ImageUrl = reader["image_url"].ToString(),
OriginalDocument = reader["original_document"].ToString() OriginalDocument = reader["original_document"].ToString()
}; };
var groupFetch = await GetGroupsAsync(fetchedFeed.GroupId); //TODO: Set group on insert
/*var groupFetch = await GetGroupsAsync(fetchedFeed.GroupId);
if (groupFetch.Any()) if (groupFetch.Any())
fetchedFeed.Group = groupFetch.First(); fetchedFeed.Group = groupFetch.First();
else else
Log.Warning("Could not get group from feed: {FeedId}", fetchedFeed.Id); Log.Warning("Could not get group from feed: {FeedId}", fetchedFeed.Id);*/
return fetchedFeed; return fetchedFeed;
} }

View File

@ -4,13 +4,11 @@ namespace SharpRss.Models
{ {
public class FeedModel public class FeedModel
{ {
public FeedModel(string rssUrl) public FeedModel()
{ {
Url = rssUrl;
} }
public CategoryModel? Group { get; set; } public CategoryModel? Group { get; set; }
public string? Id { get; set; } public string Url { get; set; }
public string? Url { get; set; }
public string? Title { get; set; } = string.Empty; public string? Title { get; set; } = string.Empty;
public string? GroupId { get; set; } = string.Empty; public string? GroupId { get; set; } = string.Empty;
public string? FeedType { get; set; } = string.Empty; public string? FeedType { get; set; } = string.Empty;

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Argotic.Common; using Argotic.Common;
@ -38,35 +39,33 @@ namespace SharpRss.Services
bool validate = SyndicationDiscoveryUtility.UriExists(new Uri(url)); bool validate = SyndicationDiscoveryUtility.UriExists(new Uri(url));
if (!validate) return false; if (!validate) return false;
// Check if feed exists in db // Check if feed exists in db
FeedModel? dbFeed = await DbAccess.GetFeedAsync(url); FeedModel? fModel = await DbAccess.GetFeedAsync(url);
if (dbFeed == null) // If not exists fetch feed & add.
if (fModel == null)
{ {
GenericSyndicationFeed genFeed = new GenericSyndicationFeed(); GenericSyndicationFeed genFeed = GenericSyndicationFeed.Create(new Uri(url));
switch (genFeed.Format) fModel = FromResource(genFeed.Resource);
{ fModel.GroupId = group?.Id;
case SyndicationContentFormat.Rss: // Add feed
RssFeed rssFeed = (RssFeed)genFeed.Resource; FeedModel? dbFeed = await DbAccess.SetFeedAsync(fModel);
break;
case SyndicationContentFormat.Atom:
AtomFeed atomFeed = (AtomFeed)genFeed.Resource;
break;
default:
Log.Information("Feed implementation missing!");
break;
}
}
// Update feed if newer
// Update/fetch items // Update/fetch items
await DbAccess.FetchFeedItemsAsync(new string[] { fModel.Url });
}
return false; return false;
} }
private static FeedModel FromResource(ISyndicationResource resource) private static FeedModel FromResource(ISyndicationResource resource)
{ {
FeedModel model = new FeedModel(""); FeedModel model = new FeedModel();
switch (resource) switch (resource.Format)
{ {
case RssFeed rssFeed: case SyndicationContentFormat.Rss:
//TODO: From feed to model RssFeed rssFeed = (RssFeed)resource;
break;
case SyndicationContentFormat.Atom:
AtomFeed atomFeed = (AtomFeed)resource;
break;
default:
Log.Information("Feed implementation missing!");
break; break;
} }
return model; return model;
@ -158,8 +157,9 @@ namespace SharpRss.Services
Log.Error(e, "Error fetching feeds!"); Log.Error(e, "Error fetching feeds!");
throw; throw;
}*/ }*/
var groups = await GetGroupsAsync(); /*var groups = await GetGroupsAsync();
CategoryModel testGroup = groups.Single(x => x.Name == "News"); CategoryModel testGroup = groups.Single(x => x.Name == "News");*/
await AddSubscriptionAsync("https://www.nu.nl/rss/Algemeen");
/*await AddFeedsAsync(new[] /*await AddFeedsAsync(new[]
{ {
"https://www.nu.nl/rss/Algemeen", "https://www.nu.nl/rss/Algemeen",

View File

@ -57,7 +57,7 @@
else if (Gid != null) else if (Gid != null)
{ {
var feeds = await _rssService.GetFeedsAsync(Gid); var feeds = await _rssService.GetFeedsAsync(Gid);
var feedIds = feeds.Select(x => x.Id); var feedIds = feeds.Select(x => x.Url);
var feedItems = await _rssService.GetFeedItemsFromFeedsAsync(feedIds.ToArray()); var feedItems = await _rssService.GetFeedItemsFromFeedsAsync(feedIds.ToArray());
items = feedItems.Select(x => FeedItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet(); items = feedItems.Select(x => FeedItemData.FromModel(x)).OrderBy(x => x.PublishingDate).Reverse().ToHashSet();
} }

View File

@ -51,7 +51,7 @@
if (_selectedItem == null) return; if (_selectedItem == null) return;
if (_selectedItem.FeedModel != null) if (_selectedItem.FeedModel != null)
{ {
_navigation.NavigateTo($"/list?fid={_selectedItem.FeedModel.Id}"); _navigation.NavigateTo($"/list?fid={_selectedItem.FeedModel.Url}");
} }
else if (_selectedItem.GroupModel != null) else if (_selectedItem.GroupModel != null)
{ {

Binary file not shown.