Coverage Report

Created: 2024-02-20 21:15

/builds/xfbs/cindy/src/server/api/query.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{common::api::*, hash::BoxHash, server::Error, Cindy, Tag};
2
use axum::{extract::State, routing::get, Json, Router};
3
use serde_qs::axum::QsQuery as Query;
4
use std::collections::BTreeSet;
5
use tokio::task::spawn_blocking;
6
7
2
async fn query(
8
2
    State(cindy): State<Cindy>,
9
2
    Query(query): Query<QueryFiles<'static>>,
10
2
) -> Result<Json<BTreeSet<BoxHash>>, Error> {
11
2
    let database = cindy.database().
await0
;
12
2
    spawn_blocking(move || database.query_hashes(&mut query.query.iter()))
13
2
        .await
?0
14
2
        .map(Json)
15
2
        .map_err(Into::into)
16
2
}
17
18
0
async fn query_tag_create(
19
0
    State(cindy): State<Cindy>,
20
0
    Json(request): Json<QueryTagCreate<String>>,
21
0
) -> Result<(), Error> {
22
0
    let mut database = cindy.database().await;
23
0
    spawn_blocking(move || {
24
0
        let transaction = database.transaction()?;
25
0
        transaction.query_tag_add(&mut request.query.iter(), &request.name, &request.value)?;
26
0
        transaction.commit()?;
27
0
        Ok(())
28
0
    })
29
0
    .await?
30
0
}
31
32
0
async fn query_tag_delete(
33
0
    State(cindy): State<Cindy>,
34
0
    Query(query): Query<QueryTagRemove<String>>,
35
0
) -> Result<(), Error> {
36
0
    let mut database = cindy.database().await;
37
0
    spawn_blocking(move || {
38
0
        let transaction = database.transaction()?;
39
0
        transaction.query_tag_remove(
40
0
            &mut query.query.iter(),
41
0
            query.name.as_deref(),
42
0
            query.value.as_deref(),
43
0
        )?;
44
0
        transaction.commit()?;
45
0
        Ok(())
46
0
    })
47
0
    .await?
48
0
}
49
50
0
async fn query_tags(
51
0
    State(cindy): State<Cindy>,
52
0
    Query(query): Query<QueryTags>,
53
0
) -> Result<Json<BTreeSet<Tag>>, Error> {
54
0
    let database = cindy.database().await;
55
0
    spawn_blocking(move || match query.mode {
56
0
        QueryTagsMode::Union => database.query_tag_union(
57
0
            &mut query.query.iter(),
58
0
            query.name.as_deref(),
59
0
            query.value.as_deref(),
60
0
        ),
61
0
        QueryTagsMode::Intersection => database.query_tag_intersection(
62
0
            &mut query.query.iter(),
63
0
            query.name.as_deref(),
64
0
            query.value.as_deref(),
65
0
        ),
66
0
    })
67
0
    .await?
68
0
    .map(Json)
69
0
    .map_err(Into::into)
70
0
}
71
72
16
pub fn router() -> Router<Cindy> {
73
16
    Router::new().route("/", get(query)).route(
74
16
        "/tags",
75
16
        get(query_tags)
76
16
            .post(query_tag_create)
77
16
            .delete(query_tag_delete),
78
16
    )
79
16
}