160 lines
6.5 KiB
C#
160 lines
6.5 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? Id;
|
|
public int? Author;
|
|
public string? Query;
|
|
}
|
|
|
|
public class DatabaseService(IOptions<BibblanOptions> options)
|
|
{
|
|
readonly BibblanOptions settings = options.Value;
|
|
|
|
public List<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(filter.Id != null)
|
|
{
|
|
query += $"id = {filter.Id}";
|
|
}
|
|
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 BookDetailVm GetBookDetails(int id)
|
|
{
|
|
var query = @"select * from books where id = @book;
|
|
select * from authors where id in (select author from books_authors_link where book = @book);
|
|
select * from books_languages_link where book = @book;
|
|
select * from publishers where id in (select publisher from books_publishers_link where book = @book);
|
|
select * from books_ratings_link where book = @book;
|
|
select * from series where id in (select series from books_series_link where book = @book);
|
|
select * from tags where id in (select tag from books_tags_link where book = @book);
|
|
select * from comments where book = @book;
|
|
select * from data where book = @book;";
|
|
|
|
using (var conn = new NpgsqlConnection(settings.BibblanConnection))
|
|
{
|
|
var results = conn.QueryMultiple(query, new { book = id });
|
|
var book = results.ReadFirst<Books>();
|
|
var authors = results.Read<Authors>();
|
|
var lang = results.Read<BooksLanguagesLink>();
|
|
var publishers = results.Read<Publishers>();
|
|
var ratings = results.Read<BooksRatingsLink>();
|
|
var series = results.Read<Series>();
|
|
var tags = results.Read<Tags>();
|
|
var comments = results.Read<Comments>();
|
|
var data = results.Read<Data>();
|
|
|
|
return new BookDetailVm
|
|
{
|
|
Book = book,
|
|
Authors = authors,
|
|
Language = lang,
|
|
Publishers = publishers,
|
|
Ratings = ratings,
|
|
Series = series,
|
|
Tags = tags,
|
|
Comments = comments,
|
|
Data = data
|
|
};
|
|
}
|
|
|
|
}
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|