cat_gateway/db/event/signed_docs/
signed_doc_body.rs

1//! `SignedDocBody` struct implementation.
2
3use futures::{Stream, StreamExt};
4
5use super::DocsQueryFilter;
6use crate::{
7    db::event::{common::query_limits::QueryLimits, error::NotFoundError, EventDB},
8    jinja::{get_template, JinjaTemplateSource},
9};
10
11/// Filtered select sql query jinja template
12pub(crate) const FILTERED_SELECT_SIGNED_DOCS_TEMPLATE: JinjaTemplateSource = JinjaTemplateSource {
13    name: "filtered_select_signed_documents.jinja.template",
14    source: include_str!("./sql/filtered_select_signed_documents.sql.jinja"),
15};
16
17/// Filtered count sql query jinja template
18pub(crate) const FILTERED_COUNT_SIGNED_DOCS_TEMPLATE: JinjaTemplateSource = JinjaTemplateSource {
19    name: "filtered_count_signed_documents.jinja.template",
20    source: include_str!("./sql/filtered_count_signed_documents.sql.jinja"),
21};
22
23/// Signed doc body event db struct
24#[derive(Debug, Clone, PartialEq)]
25pub(crate) struct SignedDocBody {
26    /// `signed_doc` table `id` field
27    id: uuid::Uuid,
28    /// `signed_doc` table `ver` field
29    ver: uuid::Uuid,
30    /// `signed_doc` table `type` field
31    doc_type: uuid::Uuid,
32    /// `signed_doc` table `authors` field
33    authors: Vec<String>,
34    /// `signed_doc` table `metadata` field
35    metadata: Option<serde_json::Value>,
36}
37
38impl SignedDocBody {
39    /// Returns the document id.
40    pub(crate) fn id(&self) -> &uuid::Uuid {
41        &self.id
42    }
43
44    /// Returns the document version.
45    pub(crate) fn ver(&self) -> &uuid::Uuid {
46        &self.ver
47    }
48
49    /// Returns the document type.
50    pub(crate) fn doc_type(&self) -> &uuid::Uuid {
51        &self.doc_type
52    }
53
54    /// Returns the document authors.
55    pub(crate) fn authors(&self) -> &Vec<String> {
56        &self.authors
57    }
58
59    /// Returns the document metadata.
60    pub(crate) fn metadata(&self) -> Option<&serde_json::Value> {
61        self.metadata.as_ref()
62    }
63
64    /// Returns all signed document fields for the event db queries
65    pub(crate) fn postgres_db_fields(&self) -> [&(dyn tokio_postgres::types::ToSql + Sync); 5] {
66        [
67            &self.id,
68            &self.ver,
69            &self.doc_type,
70            &self.authors,
71            &self.metadata,
72        ]
73    }
74
75    /// Creates a  `SignedDocBody` instance.
76    pub(crate) fn new(
77        id: uuid::Uuid, ver: uuid::Uuid, doc_type: uuid::Uuid, authors: Vec<String>,
78        metadata: Option<serde_json::Value>,
79    ) -> Self {
80        Self {
81            id,
82            ver,
83            doc_type,
84            authors,
85            metadata,
86        }
87    }
88
89    /// Loads a async stream of `SignedDocBody` from the event db.
90    pub(crate) async fn retrieve(
91        conditions: &DocsQueryFilter, query_limits: &QueryLimits,
92    ) -> anyhow::Result<impl Stream<Item = anyhow::Result<Self>>> {
93        let query_template = get_template(&FILTERED_SELECT_SIGNED_DOCS_TEMPLATE)?;
94        let query = query_template.render(serde_json::json!({
95            "conditions": conditions.to_string(),
96            "query_limits": query_limits.to_string(),
97        }))?;
98        let rows = EventDB::query_stream(&query, &[]).await?;
99        let docs = rows.map(|res_row| res_row.and_then(|row| SignedDocBody::from_row(&row)));
100        Ok(docs)
101    }
102
103    /// Loads a count of `SignedDocBody` from the event db.
104    pub(crate) async fn retrieve_count(condition: &DocsQueryFilter) -> anyhow::Result<i64> {
105        let query_template = get_template(&FILTERED_COUNT_SIGNED_DOCS_TEMPLATE)?;
106        let query = query_template.render(serde_json::json!({
107            "conditions": condition.to_string(),
108        }))?;
109        let row = EventDB::query_one(&query, &[]).await?;
110
111        match row.get(0) {
112            Some(count) => Ok(count),
113            None => Err(NotFoundError.into()),
114        }
115    }
116
117    /// Creates a  `SignedDocBody` from postgresql row object.
118    fn from_row(row: &tokio_postgres::Row) -> anyhow::Result<Self> {
119        let id = row.try_get("id")?;
120        let ver = row.try_get("ver")?;
121        let doc_type = row.try_get("type")?;
122        let authors = row.try_get("authors")?;
123        let metadata = row.try_get("metadata")?;
124        Ok(Self {
125            id,
126            ver,
127            doc_type,
128            authors,
129            metadata,
130        })
131    }
132}