Add the count of tagged files to All tags endpoint #21
@@ -166,6 +166,11 @@ pub struct AddTagRequest {
|
||||
pub tag_name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GetTagsRequest {
|
||||
pub path: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Claims;
|
||||
|
||||
26
src/tags.rs
26
src/tags.rs
@@ -10,6 +10,7 @@ use schema::{tagged_photo, tags};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::borrow::BorrowMut;
|
||||
use std::sync::Mutex;
|
||||
use crate::data::GetTagsRequest;
|
||||
|
||||
pub fn add_tag_services<T, TagD: TagDao + 'static>(app: App<T>) -> App<T>
|
||||
where
|
||||
@@ -35,7 +36,7 @@ async fn add_tag<D: TagDao>(
|
||||
let mut tag_dao = tag_dao.lock().expect("Unable to get TagDao");
|
||||
|
||||
tag_dao
|
||||
.get_all_tags()
|
||||
.get_all_tags(None)
|
||||
.and_then(|tags| {
|
||||
if let Some((_, tag)) = tags.iter().find(|t| t.1.name == tag_name) {
|
||||
Ok(tag.clone())
|
||||
@@ -60,10 +61,10 @@ async fn get_tags<D: TagDao>(
|
||||
.into_http_internal_err()
|
||||
}
|
||||
|
||||
async fn get_all_tags<D: TagDao>(_: Claims, tag_dao: web::Data<Mutex<D>>) -> impl Responder {
|
||||
async fn get_all_tags<D: TagDao>(_: Claims, tag_dao: web::Data<Mutex<D>>, query: web::Query<GetTagsRequest>) -> impl Responder {
|
||||
let mut tag_dao = tag_dao.lock().expect("Unable to get TagDao");
|
||||
tag_dao
|
||||
.get_all_tags()
|
||||
.get_all_tags(query.path.clone())
|
||||
.map(|tags| HttpResponse::Ok().json(tags.iter().map(|(tag_count, tag)|
|
||||
TagWithTagCount {
|
||||
tag: tag.clone(),
|
||||
@@ -99,7 +100,7 @@ async fn update_tags<D: TagDao>(
|
||||
let mut dao = tag_dao.lock().expect("Unable to get TagDao");
|
||||
|
||||
dao.get_tags_for_path(&request.file_name)
|
||||
.and_then(|existing_tags| dao.get_all_tags().map(|all| (existing_tags, all)))
|
||||
.and_then(|existing_tags| dao.get_all_tags(None).map(|all| (existing_tags, all)))
|
||||
.map(|(existing_tags, all_tags)| {
|
||||
let tags_to_remove = existing_tags
|
||||
.iter()
|
||||
@@ -185,7 +186,7 @@ pub struct AddTagsRequest {
|
||||
}
|
||||
|
||||
pub trait TagDao {
|
||||
fn get_all_tags(&mut self) -> anyhow::Result<Vec<(i64, Tag)>>;
|
||||
fn get_all_tags(&mut self, path: Option<String>) -> anyhow::Result<Vec<(i64, Tag)>>;
|
||||
fn get_tags_for_path(&mut self, path: &str) -> anyhow::Result<Vec<Tag>>;
|
||||
fn create_tag(&mut self, name: &str) -> anyhow::Result<Tag>;
|
||||
fn remove_tag(&mut self, tag_name: &str, path: &str) -> anyhow::Result<Option<()>>;
|
||||
@@ -210,13 +211,16 @@ impl Default for SqliteTagDao {
|
||||
}
|
||||
|
||||
impl TagDao for SqliteTagDao {
|
||||
fn get_all_tags(&mut self) -> anyhow::Result<Vec<(i64, Tag)>> {
|
||||
fn get_all_tags(&mut self, path: Option<String>) -> anyhow::Result<Vec<(i64, Tag)>> {
|
||||
// select name, count(*) from tags join tagged_photo ON tags.id = tagged_photo.tag_id GROUP BY tags.name ORDER BY COUNT(*);
|
||||
|
||||
let path = path.map(|p| p + "%").unwrap_or("%".to_string());
|
||||
let (id, name, created_time) = tags::all_columns;
|
||||
tags::table
|
||||
.inner_join(tagged_photo::table)
|
||||
.group_by(tags::id)
|
||||
.select((count_star(), id, name, created_time))
|
||||
.filter(tagged_photo::photo_name.like(path))
|
||||
.get_results(&mut self.connection)
|
||||
.map::<Vec<(i64, Tag)>, _>(|tags_with_count: Vec<(i64, i32, String, i64)>| {
|
||||
tags_with_count.iter().map(|tup| {
|
||||
@@ -367,8 +371,8 @@ mod tests {
|
||||
}
|
||||
|
||||
impl TagDao for TestTagDao {
|
||||
fn get_all_tags(&mut self) -> anyhow::Result<Vec<Tag>> {
|
||||
Ok(self.tags.borrow().clone())
|
||||
fn get_all_tags(&mut self, _option: Option<String>) -> anyhow::Result<Vec<(i64, Tag)>> {
|
||||
Ok(self.tags.borrow().iter().map(|t| (1, t.clone())).collect::<Vec<(i64, Tag)>>().clone())
|
||||
}
|
||||
|
||||
fn get_tags_for_path(&mut self, path: &str) -> anyhow::Result<Vec<Tag>> {
|
||||
@@ -470,9 +474,9 @@ mod tests {
|
||||
add_tag(claims, web::Json(body), tag_data.clone()).await;
|
||||
|
||||
let mut tag_dao = tag_data.lock().unwrap();
|
||||
let tags = tag_dao.get_all_tags().unwrap();
|
||||
let tags = tag_dao.get_all_tags(None).unwrap();
|
||||
assert_eq!(tags.len(), 1);
|
||||
assert_eq!(tags.first().unwrap().name, "test-tag");
|
||||
assert_eq!(tags.first().unwrap().1.name, "test-tag");
|
||||
let tagged_photos = tag_dao.tagged_photos.borrow();
|
||||
assert_eq!(tagged_photos["test.png"].len(), 1)
|
||||
}
|
||||
@@ -496,7 +500,7 @@ mod tests {
|
||||
remove_tagged_photo(claims, web::Json(remove_request), tag_data.clone()).await;
|
||||
|
||||
let mut tag_dao = tag_data.lock().unwrap();
|
||||
let tags = tag_dao.get_all_tags().unwrap();
|
||||
let tags = tag_dao.get_all_tags(None).unwrap();
|
||||
assert!(tags.is_empty());
|
||||
let tagged_photos = tag_dao.tagged_photos.borrow();
|
||||
let previously_added_tagged_photo = tagged_photos.get("test.png").unwrap();
|
||||
|
||||
Reference in New Issue
Block a user