From 4326b4c539ec4f3ae275de930438f246b7e7623e Mon Sep 17 00:00:00 2001 From: Arnaud Mimart <33665250+amimart@users.noreply.github.com> Date: Tue, 28 Feb 2023 19:30:45 +0100 Subject: [PATCH] feat(storage): implements objects query --- contracts/cw-storage/src/contract.rs | 73 +++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/contracts/cw-storage/src/contract.rs b/contracts/cw-storage/src/contract.rs index e939a321..53bb0346 100644 --- a/contracts/cw-storage/src/contract.rs +++ b/contracts/cw-storage/src/contract.rs @@ -3,7 +3,7 @@ use crate::ContractError::NotImplemented; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, + to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, }; use cw2::set_contract_version; @@ -238,12 +238,7 @@ pub mod query { pub fn object(deps: Deps, id: ObjectId) -> StdResult { objects() .load(deps.storage, id) - .map(|object| ObjectResponse { - id: object.id.clone(), - size: object.size, - owner: object.owner.into(), - is_pinned: object.pin_count > Uint128::zero(), - }) + .map(|object| map_object(object)) } pub fn data(deps: Deps, id: ObjectId) -> StdResult { @@ -256,7 +251,60 @@ pub mod query { after: Option, first: Option, ) -> StdResult { - Err(StdError::generic_err("Not implemented")) + let page_size = match first { + Some(req) => { + if req > BUCKET.load(deps.storage)?.pagination.max_page_size { + return Err(StdError::generic_err( + "Requested page size exceed maximum allowed", + )); + } + Ok(req) + } + _ => BUCKET + .load(deps.storage) + .map(|b| b.pagination.default_page_size), + }? as usize; + + let min_bound = match after { + Some(cursor) => { + let id: String = cursor::decode(cursor)?; + Some(Bound::exclusive(id)) + } + _ => None, + }; + + let iter = match address { + Some(raw_addr) => { + let addr = deps.api.addr_validate(raw_addr.as_str())?; + objects().idx.owner.prefix(addr).range( + deps.storage, + min_bound, + None, + Order::Ascending, + ) + } + _ => objects().range(deps.storage, min_bound, None, Order::Ascending), + }; + + let raw_objects = iter.take(page_size + 1).collect::>>()?; + let mapped_objects: Vec = raw_objects + .iter() + .take(page_size) + .map(|(_, object)| map_object(object.to_owned())) + .collect(); + + let cursor = mapped_objects + .last() + .map(|object| cursor::encode(object.id.clone())) + .unwrap_or("".to_string()); + + Ok(ObjectsResponse { + data: mapped_objects, + page_info: PageInfo { + has_next_page: raw_objects.len() > page_size, + cursor, + }, + }) } pub fn object_pins( @@ -267,6 +315,15 @@ pub mod query { ) -> StdResult { Err(StdError::generic_err("Not implemented")) } + + fn map_object(object: Object) -> ObjectResponse { + ObjectResponse { + id: object.id.clone(), + size: object.size, + owner: object.owner.into(), + is_pinned: object.pin_count > Uint128::zero(), + } + } } #[cfg(test)]