Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

searchAssets: add raw name + owner address query parameter support #118

Merged
merged 5 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion das_api/src/api/api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use sea_orm::{sea_query::ConditionType, ConnectionTrait, DbBackend, Statement};

use crate::{
feature_flag::{get_feature_flags, FeatureFlags},
validation::validate_opt_pubkey,
validation::{validate_opt_pubkey, validate_search_with_name},
};
use open_rpc_schema::document::OpenrpcDocument;
use {
Expand Down Expand Up @@ -358,6 +358,7 @@ impl ApiContract for DasApi {
after,
json_uri,
show_collection_metadata,
name,
} = payload;
// Deserialize search assets query
self.validate_pagination(&limit, &page, &before, &after)?;
Expand All @@ -370,6 +371,7 @@ impl ApiContract for DasApi {
SearchConditionType::All => ConditionType::All,
});
let owner_address = validate_opt_pubkey(&owner_address)?;
let name = validate_search_with_name(&name, &owner_address)?;
let creator_address = validate_opt_pubkey(&creator_address)?;
let delegate = validate_opt_pubkey(&delegate)?;

Expand Down Expand Up @@ -408,6 +410,7 @@ impl ApiContract for DasApi {
royalty_amount,
burnt,
json_uri,
name,
};
let sort_by = sort_by.unwrap_or_default();
let transform = AssetTransform {
Expand Down
1 change: 1 addition & 0 deletions das_api/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub struct SearchAssets {
pub json_uri: Option<String>,
#[serde(default)]
pub show_collection_metadata: Option<bool>,
pub name: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
Expand Down
17 changes: 17 additions & 0 deletions das_api/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ pub fn validate_pubkey(str_pubkey: String) -> Result<Pubkey, DasApiError> {
Pubkey::from_str(&str_pubkey).map_err(|_| DasApiError::PubkeyValidationError(str_pubkey))
}

pub fn validate_search_with_name(
name: &Option<String>,
owner: &Option<Vec<u8>>,
) -> Result<Option<Vec<u8>>, DasApiError> {
let opt_name = if let Some(n) = name {
if owner.is_none() {
return Err(DasApiError::ValidationError(
"Owner address must be provided in order to search assets by name".to_owned(),
));
}
Some(n.clone().into_bytes())
} else {
None
};
Ok(opt_name)
}

pub fn validate_opt_pubkey(pubkey: &Option<String>) -> Result<Option<Vec<u8>>, DasApiError> {
let opt_bytes = if let Some(pubkey) = pubkey {
let pubkey = Pubkey::from_str(pubkey)
Expand Down
27 changes: 26 additions & 1 deletion digital_asset_types/src/dao/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use self::sea_orm_active_enums::{
use sea_orm::{
entity::*,
sea_query::Expr,
sea_query::{ConditionType, IntoCondition},
sea_query::{ConditionType, IntoCondition, SimpleExpr},
Condition, DbErr, RelationDef,
};

Expand Down Expand Up @@ -54,6 +54,7 @@ pub struct SearchAssetsQuery {
pub royalty_amount: Option<u32>,
pub burnt: Option<bool>,
pub json_uri: Option<String>,
pub name: Option<Vec<u8>>,
}

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

num_conditions
}
Expand Down Expand Up @@ -245,6 +249,27 @@ impl SearchAssetsQuery {
joins.push(rel);
}

if let Some(n) = self.name.to_owned() {
let name_as_str = std::str::from_utf8(&n).map_err(|_| {
DbErr::Custom(
"Could not convert raw name bytes into string for comparison".to_owned(),
)
})?;

let name_expr =
SimpleExpr::Custom(format!("chain_data->>'name' LIKE '%{}%'", name_as_str).into());
conditions = conditions.add(name_expr);
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
2 changes: 1 addition & 1 deletion digital_asset_types/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ pub fn create_asset_grouping(
id: row_num,
group_key: "collection".to_string(),
slot_updated: Some(0),
verified: false,
verified: Some(false),
group_info_seq: Some(0),
},
)
Expand Down