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-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-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
|
|
|
}
|
|
|
|
|
|
|
|
pub fn books(
|
|
|
|
&self,
|
|
|
|
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()?;
|
2024-05-06 07:09:40 +00:00
|
|
|
Book::multiple(&conn, limit, cursor, 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
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn recent_books(&self, limit: u64) -> Result<Vec<Book>, DataStoreError> {
|
|
|
|
let conn = self.pool.get()?;
|
|
|
|
Book::recents(&conn, limit)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
pub fn book_author(&self, id: u64) -> Result<Author, DataStoreError> {
|
|
|
|
let conn = self.pool.get()?;
|
|
|
|
Author::book_author(&conn, id)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn series(
|
|
|
|
&self,
|
|
|
|
limit: u64,
|
|
|
|
cursor: Option<&str>,
|
|
|
|
sort_order: SortOrder,
|
|
|
|
) -> Result<Vec<Series>, DataStoreError> {
|
|
|
|
let conn = self.pool.get()?;
|
|
|
|
Series::multiple(&conn, limit, cursor, sort_order)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
pub fn has_previous_authors(&self, author_sort: &str) -> Result<bool, DataStoreError> {
|
|
|
|
let conn = self.pool.get()?;
|
|
|
|
Author::has_previous_authors(&conn, author_sort)
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
pub fn scalar_author(&self, id: u64) -> Result<Author, DataStoreError> {
|
|
|
|
let conn = self.pool.get()?;
|
|
|
|
Author::scalar_author(&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-01 14:21:07 +00:00
|
|
|
let books = c.books(10, None, SortOrder::ASC).unwrap();
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|