Files
bibblan/Server/Business/Services/DatabaseService.cs

113 lines
4.4 KiB
C#

using Bibblan.Models;
using Bibblan.ViewModels;
using Dapper;
using Microsoft.Extensions.Options;
using Npgsql;
namespace Bibblan.Business.Services
{
public class BookFilter
{
public int? Author;
public string? Query;
}
public class DatabaseService(IOptions<BibblanOptions> options)
{
readonly BibblanOptions settings = options.Value;
public IEnumerable<Books> GetBooks(int count, BookFilter filter = null)
{
var conn = new NpgsqlConnection(settings.BibblanConnection);
var query = "select * from books";
object parameters = null;
if (filter != null)
{
query += " where ";
if(filter.Author != null)
{
query += $"id in (select book from books_authors_link where author = {filter.Author})";
} else if(!String.IsNullOrWhiteSpace(query))
{
filter.Query = filter.Query.ToLowerInvariant();
query += $"lower(title) like @query or lower(author_sort) like @query";
parameters = new { query = "%" + filter.Query + "%" };
}
}
return conn.Query<Books>(query, parameters).Take(count).ToList();
}
public IEnumerable<AuthorVm> GetAuthors(int count, BookFilter filter = null)
{
var query = "select a.id, a.name, count(bal.*) as bookcount\r\nfrom authors a\r\nleft join books_authors_link bal on a.id = bal.author\r\ngroup by a.id , a.name ";
object parameters = null;
if (!String.IsNullOrWhiteSpace(filter?.Query))
{
filter.Query = filter.Query.ToLowerInvariant();
query += $" having lower(a.name) like @query";
parameters = new { query = "%" + filter.Query + "%" };
}
var conn = new NpgsqlConnection(settings.BibblanConnection);
return conn.Query<AuthorVm>(query, parameters).Take(count).ToList();
}
internal List<SeriesVm> GetSeries(int count, BookFilter? filter)
{
var query = @"select s.id as seriesid, s.name as seriesname, b.*, a.*
from series s
inner join books_series_link bsl on s.id = bsl.series
inner join books b on bsl.book = b.id
inner join books_authors_link bal on b.id = bal.book
inner join authors a on bal.author = a.id";
object parameters = null;
if (!String.IsNullOrWhiteSpace(filter?.Query))
{
filter.Query = filter.Query?.ToLowerInvariant().Trim() ?? "";
query += $" where lower(s.name) like @query";
parameters = new { query = "%" + filter.Query + "%" };
}
var conn = new NpgsqlConnection(settings.BibblanConnection);
var lookup = new Dictionary<long, SeriesVm>();
conn.Query<SeriesVm, Books, Authors, SeriesVm>(query, (s,b,a) =>
{
if (!lookup.TryGetValue(s.Id, out SeriesVm svm))
{
lookup.Add(s.Id, svm = s);
}
svm.Books.Add(new ListBook
{
AuthorId = a.Id,
AuthorName = a.Name,
Id = b.Id,
PubDate = b.Pubdate,
HasCover = b.HasCover,
Path = b.Path,
SeriesIndex = b.SeriesIndex,
Title = b.Title
});
return svm;
}, splitOn: "id", param: parameters);
return lookup.Values.Take(count).ToList();
}
internal List<Tag> GetTags(BookFilter? filter)
{
var query = @"select t.id, t.name, count(btl.*) as bookcount from tags t
inner join books_tags_link btl on t.id = btl.tag
group by t.id, t.name
order by bookcount desc";
object parameters = null;
if (!String.IsNullOrWhiteSpace(filter?.Query))
{
filter.Query = filter.Query.ToLowerInvariant();
query += $" having lower(name) like @query";
parameters = new { query = "%" + filter.Query + "%" };
}
var conn = new NpgsqlConnection(settings.BibblanConnection);
return conn.Query<Tag>(query,parameters).ToList();
}
}
}