Skip to content

Commit

Permalink
feat(das-api): support searching assets by jsonUri parameter (#79) (#…
Browse files Browse the repository at this point in the history
…78)

* feat(das-api): support searching assets by `jsonUri` parameter (#79)

* add dto parameter

* add dao condition

* upd asset_data fetching to ensure single presence of asset_data in query

* use asset.asset_data key for linking between asset/asset_data

* fix: breaking arg order for array queries

* chore: consistent arg order in `SearchAssets` destructuring

* fix: breaking arg count for array params in searchAssets

* Cargo fmt

---------

Co-authored-by: Alex Tsymbal <[email protected]>
  • Loading branch information
linuskendall and tsmbl authored Jun 21, 2023
1 parent 109a45a commit d085935
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 17 deletions.
2 changes: 2 additions & 0 deletions das_api/src/api/api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ impl ApiContract for DasApi {
page,
before,
after,
json_uri
} = payload;
// Deserialize search assets query
self.validate_pagination(&limit, &page, &before, &after)?;
Expand Down Expand Up @@ -322,6 +323,7 @@ impl ApiContract for DasApi {
royalty_target,
royalty_amount,
burnt,
json_uri,
};
let sort_by = sort_by.unwrap_or_default();
// Execute query
Expand Down
3 changes: 2 additions & 1 deletion das_api/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ pub struct SearchAssets {
pub page: Option<u32>,
pub before: Option<String>,
pub after: Option<String>,
#[serde(default)]
pub json_uri: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]

pub struct GetAssetsByAuthority {
pub authority_address: String,
pub sort_by: Option<AssetSorting>,
Expand Down
18 changes: 18 additions & 0 deletions digital_asset_types/src/dao/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub struct SearchAssetsQuery {
pub royalty_target: Option<Vec<u8>>,
pub royalty_amount: Option<u32>,
pub burnt: Option<bool>,
pub json_uri: Option<String>,
}

impl SearchAssetsQuery {
Expand Down Expand Up @@ -111,6 +112,9 @@ impl SearchAssetsQuery {
if self.grouping.is_some() {
num_conditions += 1;
}
if self.json_uri.is_some() {
num_conditions += 1;
}

num_conditions
}
Expand Down Expand Up @@ -223,6 +227,20 @@ impl SearchAssetsQuery {
joins.push(rel);
}

if let Some(ju) = self.json_uri.to_owned() {
let cond = Condition::all().add(asset_data::Column::MetadataUrl.eq(ju));
conditions = conditions.add(cond);
let rel = asset_data::Relation::Asset
.def()
.rev()
.on_condition(|left, right| {
Expr::tbl(right, asset_data::Column::Id)
.eq(Expr::tbl(left, asset::Column::AssetData))
.into_condition()
});
joins.push(rel);
}

Ok((
match self.negate {
None | Some(false) => conditions,
Expand Down
43 changes: 27 additions & 16 deletions digital_asset_types/src/dao/scopes/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::dao::{
Pagination,
};
use sea_orm::{entity::*, query::*, ConnectionTrait, DbErr, Order};
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};

pub fn paginate<T>(pagination: &Pagination, limit: u64, stmt: T) -> T
where
Expand Down Expand Up @@ -156,7 +156,6 @@ where
E: RelationTrait,
{
let mut stmt = asset::Entity::find()
.find_also_related(asset_data::Entity)
.filter(condition)
.join(JoinType::LeftJoin, relation.def())
.distinct_on([(asset::Entity, asset::Column::Id)])
Expand All @@ -172,27 +171,39 @@ where

pub async fn get_related_for_assets(
conn: &impl ConnectionTrait,
assets: Vec<(asset::Model, Option<asset_data::Model>)>,
assets: Vec<asset::Model>,
) -> Result<Vec<FullAsset>, DbErr> {
let mut ids = Vec::with_capacity(assets.len());
let asset_ids = assets.iter().map(|a| a.id.clone()).collect::<Vec<_>>();

let asset_data: Vec<asset_data::Model> = asset_data::Entity::find()
.filter(asset_data::Column::Id.is_in(asset_ids))
.all(conn)
.await?;
let asset_data_map = asset_data.into_iter().fold(HashMap::new(), |mut acc, ad| {
acc.insert(ad.id.clone(), ad);
acc
});

// Using BTreeMap to preserve order.
let mut assets_map = assets.into_iter().fold(BTreeMap::new(), |mut x, asset| {
if let Some(ad) = asset.1 {
let id = asset.0.id.clone();
let mut assets_map = assets.into_iter().fold(BTreeMap::new(), |mut acc, asset| {
if let Some(ad) = asset
.asset_data
.clone()
.and_then(|ad_id| asset_data_map.get(&ad_id))
{
let id = asset.id.clone();
let fa = FullAsset {
asset: asset.0,
data: ad,
asset: asset,
data: ad.clone(),
authorities: vec![],
creators: vec![],
groups: vec![],
};

x.insert(id.clone(), fa);
ids.push(id);
}
x
acc.insert(id, fa);
};
acc
});

let ids = assets_map.keys().cloned().collect::<Vec<_>>();
let authorities = asset_authority::Entity::find()
.filter(asset_authority::Column::AssetId.is_in(ids.clone()))
.order_by_asc(asset_authority::Column::AssetId)
Expand Down Expand Up @@ -248,7 +259,7 @@ pub async fn get_assets_by_condition(
.order_by(sort_by, sort_direction);

stmt = paginate(pagination, limit, stmt);
let asset_list = stmt.find_also_related(asset_data::Entity).all(conn).await?;
let asset_list = stmt.all(conn).await?;
get_related_for_assets(conn, asset_list).await
}

Expand Down

0 comments on commit d085935

Please sign in to comment.