Skip to content

Commit 8e51bf3

Browse files
feat(cat-gateway): Update filtering options for the 'v2/document/index' endpoint (#3653)
* Update filtering options for the 'v2/document/index' endpoint * Rename 'EqOrRangedUuid' to 'UuidSelector' * DocumentIdList and VerIdList types * Implement PartialEq * Return an error if Id or Ver selector lists are empty * Bump api version * Revert error changes * Handle empty Id/Ver In selector * Fix tests --------- Co-authored-by: Alex Pozhylenkov <[email protected]>
1 parent a64c0fc commit 8e51bf3

File tree

16 files changed

+264
-129
lines changed

16 files changed

+264
-129
lines changed

catalyst-gateway/bin/src/db/event/common/eq_or_ranged_uuid.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! `EqOrRangedUuid` query conditional stmt object.
22
3-
/// Search either by a singe UUID, or a Range of UUIDs
3+
/// Search either by a singe UUID, a range of UUIDs or a list of UUIDs.
44
#[derive(Clone, Debug, PartialEq)]
5-
pub(crate) enum EqOrRangedUuid {
5+
pub(crate) enum UuidSelector {
66
/// Search by the exact UUID
77
Eq(uuid::Uuid),
88
/// Search in this UUID's range
@@ -12,9 +12,11 @@ pub(crate) enum EqOrRangedUuid {
1212
/// Maximum UUID to find (inclusive)
1313
max: uuid::Uuid,
1414
},
15+
/// Search UUIDs in the given list.
16+
In(Vec<uuid::Uuid>),
1517
}
1618

17-
impl EqOrRangedUuid {
19+
impl UuidSelector {
1820
/// Return a sql conditional statement by the provided `table_field`
1921
pub(crate) fn conditional_stmt(
2022
&self,
@@ -25,6 +27,13 @@ impl EqOrRangedUuid {
2527
Self::Range { min, max } => {
2628
format!("{table_field} >= '{min}' AND {table_field} <= '{max}'")
2729
},
30+
Self::In(ids) => {
31+
itertools::intersperse(
32+
ids.iter().map(|id| format!("{table_field} = '{id}'")),
33+
" OR ".to_string(),
34+
)
35+
.collect()
36+
},
2837
}
2938
}
3039
}

catalyst-gateway/bin/src/db/event/signed_docs/doc_ref.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
33
use std::fmt::Write;
44

5-
use crate::db::event::common::eq_or_ranged_uuid::EqOrRangedUuid;
5+
use crate::db::event::common::eq_or_ranged_uuid::UuidSelector;
66

77
/// Document Reference filtering struct.
88
#[derive(Clone, Debug)]
99
pub(crate) struct DocumentRef {
1010
/// Document id filtering
11-
pub(crate) id: Option<EqOrRangedUuid>,
11+
pub(crate) id: Option<UuidSelector>,
1212
/// Document ver filtering
13-
pub(crate) ver: Option<EqOrRangedUuid>,
13+
pub(crate) ver: Option<UuidSelector>,
1414
}
1515

1616
impl DocumentRef {

catalyst-gateway/bin/src/db/event/signed_docs/query_filter.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::fmt::Display;
44

55
use super::DocumentRef;
6-
use crate::db::event::common::eq_or_ranged_uuid::EqOrRangedUuid;
6+
use crate::db::event::common::eq_or_ranged_uuid::UuidSelector;
77

88
/// A `select_signed_docs` query filtering argument.
99
/// If all fields would be `None` the query will search for all entries from the db.
@@ -12,9 +12,9 @@ pub(crate) struct DocsQueryFilter {
1212
/// `type` field. Empty list if unspecified.
1313
doc_type: Vec<uuid::Uuid>,
1414
/// `id` field. `None` if unspecified.
15-
id: Option<EqOrRangedUuid>,
15+
id: Option<UuidSelector>,
1616
/// `ver` field. `None` if unspecified.
17-
ver: Option<EqOrRangedUuid>,
17+
ver: Option<UuidSelector>,
1818
/// `metadata->'ref'` field. Empty list if unspecified.
1919
doc_ref: Vec<DocumentRef>,
2020
/// `metadata->'template'` field. Empty list if unspecified.
@@ -95,7 +95,7 @@ impl DocsQueryFilter {
9595
/// Set the `id` field filter condition
9696
pub fn with_id(
9797
self,
98-
id: EqOrRangedUuid,
98+
id: UuidSelector,
9999
) -> Self {
100100
DocsQueryFilter {
101101
id: Some(id),
@@ -106,7 +106,7 @@ impl DocsQueryFilter {
106106
/// Set the `ver` field filter condition
107107
pub fn with_ver(
108108
self,
109-
ver: EqOrRangedUuid,
109+
ver: UuidSelector,
110110
) -> Self {
111111
DocsQueryFilter {
112112
ver: Some(ver),

catalyst-gateway/bin/src/db/event/signed_docs/tests/filter_by_field.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ macro_rules! filter_by_field {
1212

1313
// With id
1414
let filter = DocsQueryFilter::all().$with_method(DocumentRef {
15-
id: Some(EqOrRangedUuid::Eq(id)),
15+
id: Some(UuidSelector::Eq(id)),
1616
ver: None,
1717
});
1818
let mut res_docs = SignedDocBody::retrieve(&filter, &QueryLimits::ALL)
@@ -24,7 +24,7 @@ macro_rules! filter_by_field {
2424
// With ver
2525
let filter = DocsQueryFilter::all().$with_method(DocumentRef {
2626
id: None,
27-
ver: Some(EqOrRangedUuid::Eq(ver)),
27+
ver: Some(UuidSelector::Eq(ver)),
2828
});
2929
let mut res_docs = SignedDocBody::retrieve(&filter, &QueryLimits::ALL)
3030
.await
@@ -34,8 +34,8 @@ macro_rules! filter_by_field {
3434

3535
// With both id and ver
3636
let filter = DocsQueryFilter::all().$with_method(DocumentRef {
37-
id: Some(EqOrRangedUuid::Eq(id)),
38-
ver: Some(EqOrRangedUuid::Eq(ver)),
37+
id: Some(UuidSelector::Eq(id)),
38+
ver: Some(UuidSelector::Eq(ver)),
3939
});
4040
let mut res_docs = SignedDocBody::retrieve(&filter, &QueryLimits::ALL)
4141
.await

catalyst-gateway/bin/src/db/event/signed_docs/tests/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use futures::TryStreamExt;
66

77
use super::*;
88
use crate::db::event::{
9-
common::{eq_or_ranged_uuid::EqOrRangedUuid, query_limits::QueryLimits},
9+
common::{eq_or_ranged_uuid::UuidSelector, query_limits::QueryLimits},
1010
establish_connection_pool,
1111
};
1212

@@ -122,15 +122,15 @@ async fn retrieve_full_signed_doc(doc: &FullSignedDoc) {
122122
}
123123

124124
async fn filter_by_id(doc: &FullSignedDoc) {
125-
let filter = DocsQueryFilter::all().with_id(EqOrRangedUuid::Eq(*doc.id()));
125+
let filter = DocsQueryFilter::all().with_id(UuidSelector::Eq(*doc.id()));
126126
let mut res_docs = SignedDocBody::retrieve(&filter, &QueryLimits::ALL)
127127
.await
128128
.unwrap();
129129
let res_doc = res_docs.try_next().await.unwrap().unwrap();
130130
assert_eq!(doc.body(), &res_doc);
131131
assert!(res_docs.try_next().await.unwrap().is_none());
132132

133-
let filter = DocsQueryFilter::all().with_id(EqOrRangedUuid::Range {
133+
let filter = DocsQueryFilter::all().with_id(UuidSelector::Range {
134134
min: *doc.id(),
135135
max: *doc.id(),
136136
});
@@ -143,15 +143,15 @@ async fn filter_by_id(doc: &FullSignedDoc) {
143143
}
144144

145145
async fn filter_by_ver(doc: &FullSignedDoc) {
146-
let filter = DocsQueryFilter::all().with_ver(EqOrRangedUuid::Eq(*doc.ver()));
146+
let filter = DocsQueryFilter::all().with_ver(UuidSelector::Eq(*doc.ver()));
147147
let mut res_docs = SignedDocBody::retrieve(&filter, &QueryLimits::ALL)
148148
.await
149149
.unwrap();
150150
let res_doc = res_docs.try_next().await.unwrap().unwrap();
151151
assert_eq!(doc.body(), &res_doc);
152152
assert!(res_docs.try_next().await.unwrap().is_none());
153153

154-
let filter = DocsQueryFilter::all().with_ver(EqOrRangedUuid::Range {
154+
let filter = DocsQueryFilter::all().with_ver(UuidSelector::Range {
155155
min: *doc.ver(),
156156
max: *doc.ver(),
157157
});
@@ -165,8 +165,8 @@ async fn filter_by_ver(doc: &FullSignedDoc) {
165165

166166
async fn filter_by_id_and_ver(doc: &FullSignedDoc) {
167167
let filter = DocsQueryFilter::all()
168-
.with_id(EqOrRangedUuid::Eq(*doc.id()))
169-
.with_ver(EqOrRangedUuid::Eq(*doc.ver()));
168+
.with_id(UuidSelector::Eq(*doc.id()))
169+
.with_ver(UuidSelector::Eq(*doc.ver()));
170170
let mut res_docs = SignedDocBody::retrieve(&filter, &QueryLimits::ALL)
171171
.await
172172
.unwrap();

catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/v2/key_data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub struct KeyData {
5151

5252
impl KeyData {
5353
/// Creates a new `KeyData` instance.
54-
pub fn new(
54+
pub(crate) fn new(
5555
is_persistent: bool,
5656
time: DateTime,
5757
slot: SlotNo,

catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/v2/payment_data.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct PaymentData {
2626

2727
impl PaymentData {
2828
/// Creates a new `PaymentData` instance.
29-
pub fn new(
29+
pub(crate) fn new(
3030
is_persistent: bool,
3131
time: DateTime,
3232
slot: SlotNo,

catalyst-gateway/bin/src/service/api/documents/post_document_index_query/v2/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub(crate) enum Responses {
3939
///
4040
/// The Index of documents which match the query filter.
4141
#[oai(status = 200)]
42-
Ok(Json<response::DocumentIndexListDocumentedV2>),
42+
Ok(Json<DocumentIndexListDocumentedV2>),
4343
/// ## Not Found
4444
///
4545
/// No documents were found which match the query filter.

catalyst-gateway/bin/src/service/api/documents/post_document_index_query/v2/request.rs

Lines changed: 9 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::{
1010
service::common::types::{
1111
array_types::impl_array_types,
1212
document::{
13-
doc_type::DocumentType, id::EqOrRangedIdDocumented,
14-
id_and_ver_ref::IdAndVerRefDocumented, ver::EqOrRangedVerDocumented,
13+
doc_type::DocumentType, id::IdSelectorDocumented,
14+
id_and_ver_ref::IdAndVerRefDocumented, ver::VerSelectorDocumented,
1515
},
1616
},
1717
};
@@ -38,13 +38,13 @@ pub(crate) struct DocumentIndexQueryFilterV2 {
3838
/// Either an absolute single Document ID or a range of
3939
/// [Document IDs](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/spec/#id)
4040
#[oai(skip_serializing_if_is_none)]
41-
id: Option<EqOrRangedIdDocumentedList>,
41+
id: Option<IdSelectorDocumented>,
4242
/// ## Document Version
4343
///
4444
/// Either an absolute single Document Version or a range of
4545
/// [Document Versions](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/spec/#ver)
4646
#[oai(skip_serializing_if_is_none)]
47-
ver: Option<EqOrRangedVerDocumentedList>,
47+
ver: Option<VerSelectorDocumented>,
4848
/// ## Document Reference
4949
///
5050
/// A [reference](https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/meta/#ref-document-reference)
@@ -146,23 +146,6 @@ impl Example for DocumentIndexQueryFilterV2 {
146146
}
147147
}
148148

149-
impl_array_types!(
150-
EqOrRangedIdDocumentedList,
151-
EqOrRangedIdDocumented,
152-
Some(poem_openapi::registry::MetaSchema {
153-
example: Self::example().to_json(),
154-
max_items: Some(10),
155-
items: Some(Box::new(EqOrRangedIdDocumented::schema_ref())),
156-
..poem_openapi::registry::MetaSchema::ANY
157-
})
158-
);
159-
160-
impl Example for EqOrRangedIdDocumentedList {
161-
fn example() -> Self {
162-
Self(vec![EqOrRangedIdDocumented::example()])
163-
}
164-
}
165-
166149
impl_array_types!(
167150
DocumentTypeList,
168151
DocumentType,
@@ -180,23 +163,6 @@ impl Example for DocumentTypeList {
180163
}
181164
}
182165

183-
impl_array_types!(
184-
EqOrRangedVerDocumentedList,
185-
EqOrRangedVerDocumented,
186-
Some(poem_openapi::registry::MetaSchema {
187-
example: Self::example().to_json(),
188-
max_items: Some(10),
189-
items: Some(Box::new(EqOrRangedVerDocumented::schema_ref())),
190-
..poem_openapi::registry::MetaSchema::ANY
191-
})
192-
);
193-
194-
impl Example for EqOrRangedVerDocumentedList {
195-
fn example() -> Self {
196-
Self(vec![EqOrRangedVerDocumented::example()])
197-
}
198-
}
199-
200166
impl_array_types!(
201167
IdAndVerRefDocumentedList,
202168
IdAndVerRefDocumented,
@@ -247,26 +213,14 @@ impl TryFrom<DocumentIndexQueryFilterV2> for DocsQueryFilter {
247213
.collect::<Result<Vec<_>, _>>()?,
248214
);
249215
}
250-
if let Some(ids) = value.id {
251-
let ids = ids
252-
.0
253-
.into_iter()
254-
.map(TryInto::try_into)
255-
.collect::<Result<Vec<_>, _>>()?;
256-
257-
for id in ids {
216+
if let Some(id) = value.id {
217+
if let Some(id) = id.try_into()? {
258218
db_filter = db_filter.with_id(id);
259219
}
260220
}
261-
if let Some(versions) = value.ver {
262-
let versions = versions
263-
.0
264-
.into_iter()
265-
.map(TryInto::try_into)
266-
.collect::<Result<Vec<_>, _>>()?;
267-
268-
for ver in versions {
269-
db_filter = db_filter.with_ver(ver);
221+
if let Some(version) = value.ver {
222+
if let Some(version) = version.try_into()? {
223+
db_filter = db_filter.with_ver(version);
270224
}
271225
}
272226
if let Some(doc_refs) = value.doc_ref {

catalyst-gateway/bin/src/service/api/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub(crate) mod health;
2323
const API_TITLE: &str = "Catalyst Gateway";
2424

2525
/// The version of the API
26-
const API_VERSION: &str = "0.7.0";
26+
const API_VERSION: &str = "0.8.0";
2727

2828
/// Get the contact details for inquiring about the API
2929
fn get_api_contact() -> ContactObject {

0 commit comments

Comments
 (0)