little-hesinde/calibre-db/src/calibre.rs

213 lines
6.9 KiB
Rust
Raw Normal View History

2024-05-10 12:25:18 +00:00
//! Bundle all functions together.
2024-05-02 16:10:29 +00:00
use std::path::Path;
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
2024-05-01 14:21:07 +00:00
2024-05-06 07:09:40 +00:00
use crate::data::{
author::Author, book::Book, error::DataStoreError, pagination::SortOrder, series::Series,
};
2024-05-01 14:21:07 +00:00
2024-05-10 12:25:18 +00:00
/// Top level calibre functions, bundling all sub functions in one place and providing secure access to
/// the database.
2024-05-02 16:10:29 +00:00
#[derive(Debug, Clone)]
2024-05-01 14:21:07 +00:00
pub struct Calibre {
2024-05-02 16:10:29 +00:00
pool: Pool<SqliteConnectionManager>,
2024-05-01 14:21:07 +00:00
}
impl Calibre {
2024-05-10 12:25:18 +00:00
/// Open a connection to the calibre database.
///
/// Fail if the database file can not be opened or not be found.
2024-05-02 16:10:29 +00:00
pub fn load(path: &Path) -> Result<Self, DataStoreError> {
let manager = SqliteConnectionManager::file(path);
let pool = r2d2::Pool::new(manager)?;
Ok(Self { pool })
2024-05-01 14:21:07 +00:00
}
2024-05-10 12:25:18 +00:00
/// Fetch book data from calibre, starting at `cursor`, fetching up to an amount of `limit` and
/// ordering by `sort_order`.
2024-05-01 14:21:07 +00:00
pub fn books(
&self,
limit: u64,
cursor: Option<&str>,
2024-05-06 12:42:14 +00:00
sort_order: &SortOrder,
2024-05-01 14:21:07 +00:00
) -> Result<Vec<Book>, DataStoreError> {
2024-05-02 16:10:29 +00:00
let conn = self.pool.get()?;
2024-05-06 07:09:40 +00:00
Book::multiple(&conn, limit, cursor, sort_order)
2024-05-01 14:21:07 +00:00
}
2024-05-10 12:25:18 +00:00
/// Fetch author data from calibre, starting at `cursor`, fetching up to an amount of `limit` and
/// ordering by `sort_order`.
2024-05-01 14:21:07 +00:00
pub fn authors(
&self,
limit: u64,
cursor: Option<&str>,
2024-05-06 11:51:49 +00:00
sort_order: &SortOrder,
2024-05-01 14:21:07 +00:00
) -> Result<Vec<Author>, DataStoreError> {
2024-05-02 16:10:29 +00:00
let conn = self.pool.get()?;
2024-05-06 07:09:40 +00:00
Author::multiple(&conn, limit, cursor, sort_order)
2024-05-01 14:21:07 +00:00
}
2024-05-10 12:25:18 +00:00
/// Fetch books for an author specified by `author_id`, paginate the books by starting at `cursor`,
/// fetching up to an amount of `limit` and ordering by `sort_order`.
2024-05-01 14:21:07 +00:00
pub fn author_books(
&self,
author_id: u64,
limit: u64,
cursor: Option<&str>,
sort_order: SortOrder,
) -> Result<Vec<Book>, DataStoreError> {
2024-05-02 16:10:29 +00:00
let conn = self.pool.get()?;
Book::author_books(&conn, author_id, limit, cursor, sort_order)
}
2024-05-10 12:25:18 +00:00
/// Get recent books up to a limit of `limit`.
2024-05-02 16:10:29 +00:00
pub fn recent_books(&self, limit: u64) -> Result<Vec<Book>, DataStoreError> {
let conn = self.pool.get()?;
Book::recents(&conn, limit)
}
2024-05-10 12:25:18 +00:00
/// Get a single book, specified `id`.
2024-05-02 16:10:29 +00:00
pub fn scalar_book(&self, id: u64) -> Result<Book, DataStoreError> {
let conn = self.pool.get()?;
Book::scalar_book(&conn, id)
2024-05-01 14:21:07 +00:00
}
2024-05-06 07:09:40 +00:00
2024-05-10 12:25:18 +00:00
/// Get the author to a book with id `id`.
2024-05-06 07:09:40 +00:00
pub fn book_author(&self, id: u64) -> Result<Author, DataStoreError> {
let conn = self.pool.get()?;
Author::book_author(&conn, id)
}
2024-05-10 12:25:18 +00:00
/// Fetch series data from calibre, starting at `cursor`, fetching up to an amount of `limit` and
/// ordering by `sort_order`.
2024-05-06 07:09:40 +00:00
pub fn series(
&self,
limit: u64,
cursor: Option<&str>,
2024-05-06 14:25:15 +00:00
sort_order: &SortOrder,
2024-05-06 07:09:40 +00:00
) -> Result<Vec<Series>, DataStoreError> {
let conn = self.pool.get()?;
Series::multiple(&conn, limit, cursor, sort_order)
}
2024-05-10 12:25:18 +00:00
/// Get the series a book with id `id` is in, as well as the book's position within the series.
2024-05-06 07:09:40 +00:00
pub fn book_series(&self, id: u64) -> Result<Option<(Series, f64)>, DataStoreError> {
let conn = self.pool.get()?;
Series::book_series(&conn, id)
}
2024-05-06 11:51:49 +00:00
2024-05-10 12:25:18 +00:00
/// Get all books belonging to the series with id `id`.
2024-05-06 14:25:15 +00:00
pub fn series_books(&self, id: u64) -> Result<Vec<Book>, DataStoreError> {
let conn = self.pool.get()?;
Book::series_books(&conn, id)
}
2024-05-10 12:25:18 +00:00
/// Check if there are more authors before the specified cursor.
2024-05-06 11:51:49 +00:00
pub fn has_previous_authors(&self, author_sort: &str) -> Result<bool, DataStoreError> {
let conn = self.pool.get()?;
Author::has_previous_authors(&conn, author_sort)
}
2024-05-10 12:25:18 +00:00
/// Check if there are more authors after the specified cursor.
2024-05-06 11:51:49 +00:00
pub fn has_more_authors(&self, author_sort: &str) -> Result<bool, DataStoreError> {
let conn = self.pool.get()?;
Author::has_more_authors(&conn, author_sort)
}
2024-05-06 12:17:25 +00:00
2024-05-10 12:25:18 +00:00
/// Check if there are more books before the specified cursor.
2024-05-06 12:42:14 +00:00
pub fn has_previous_books(&self, book_sort: &str) -> Result<bool, DataStoreError> {
let conn = self.pool.get()?;
Book::has_previous_books(&conn, book_sort)
}
2024-05-10 12:25:18 +00:00
/// Check if there are more books after the specified cursor.
2024-05-06 12:42:14 +00:00
pub fn has_more_books(&self, book_sort: &str) -> Result<bool, DataStoreError> {
let conn = self.pool.get()?;
Book::has_more_books(&conn, book_sort)
}
2024-05-10 12:25:18 +00:00
/// Check if there are more series before the specified cursor.
2024-05-06 14:25:15 +00:00
pub fn has_previous_series(&self, series_sort: &str) -> Result<bool, DataStoreError> {
let conn = self.pool.get()?;
Series::has_previous_series(&conn, series_sort)
}
2024-05-10 12:25:18 +00:00
/// Check if there are more series after the specified cursor.
2024-05-06 14:25:15 +00:00
pub fn has_more_series(&self, series_sort: &str) -> Result<bool, DataStoreError> {
let conn = self.pool.get()?;
Series::has_more_series(&conn, series_sort)
}
2024-05-10 12:25:18 +00:00
/// Fetch a single author with id `id`.
2024-05-06 12:17:25 +00:00
pub fn scalar_author(&self, id: u64) -> Result<Author, DataStoreError> {
let conn = self.pool.get()?;
Author::scalar_author(&conn, id)
}
2024-05-06 14:25:15 +00:00
2024-05-10 12:25:18 +00:00
/// Fetch a single series with id `id`.
2024-05-06 14:25:15 +00:00
pub fn scalar_series(&self, id: u64) -> Result<Series, DataStoreError> {
let conn = self.pool.get()?;
Series::scalar_series(&conn, id)
}
2024-05-01 14:21:07 +00:00
}
#[cfg(test)]
mod tests {
use super::*;
2024-05-02 16:10:29 +00:00
fn init_calibre() -> Calibre {
Calibre::load(Path::new("./testdata/metadata.db")).unwrap()
}
2024-05-01 14:21:07 +00:00
#[test]
fn books() {
2024-05-02 16:10:29 +00:00
let c = init_calibre();
2024-05-06 12:42:14 +00:00
let books = c.books(10, None, &SortOrder::ASC).unwrap();
2024-05-01 14:21:07 +00:00
assert_eq!(books.len(), 4);
}
#[test]
fn authors() {
2024-05-02 16:10:29 +00:00
let c = init_calibre();
2024-05-06 11:51:49 +00:00
let authors = c.authors(10, None, &SortOrder::ASC).unwrap();
2024-05-01 14:21:07 +00:00
assert_eq!(authors.len(), 3);
}
#[test]
fn author_books() {
2024-05-02 16:10:29 +00:00
let c = init_calibre();
2024-05-01 14:21:07 +00:00
let books = c.author_books(1, 10, None, SortOrder::ASC).unwrap();
assert_eq!(books.len(), 2);
}
#[test]
fn pagination() {
2024-05-02 16:10:29 +00:00
let c = init_calibre();
2024-05-06 11:51:49 +00:00
let authors = c.authors(1, None, &SortOrder::ASC).unwrap();
2024-05-01 14:21:07 +00:00
assert_eq!(authors.len(), 1);
assert_eq!(authors[0].name, "Kevin R. Grazier");
let authors = c
2024-05-06 11:51:49 +00:00
.authors(1, Some(&authors[0].sort), &SortOrder::ASC)
2024-05-01 14:21:07 +00:00
.unwrap();
assert_eq!(authors.len(), 1);
assert_eq!(authors[0].name, "Terry Pratchett");
let authors = c
2024-05-06 11:51:49 +00:00
.authors(1, Some(&authors[0].sort), &SortOrder::ASC)
2024-05-01 14:21:07 +00:00
.unwrap();
assert_eq!(authors.len(), 1);
assert_eq!(authors[0].name, "Edward Noyes Westcott");
let authors = c
2024-05-06 11:51:49 +00:00
.authors(1, Some(&authors[0].sort), &SortOrder::DESC)
2024-05-01 14:21:07 +00:00
.unwrap();
assert_eq!(authors.len(), 1);
assert_eq!(authors[0].name, "Terry Pratchett");
}
}