Skip to content

Commit

Permalink
Update cw721-base with new index format
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanfrey committed Oct 16, 2020
1 parent fad0402 commit ae42b7d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 18 deletions.
21 changes: 11 additions & 10 deletions contracts/cw721-base/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ use cw721::{
use crate::error::ContractError;
use crate::msg::{HandleMsg, InitMsg, MintMsg, MinterResponse, QueryMsg};
use crate::state::{
increment_tokens, num_tokens, tokens, Approval, TokenInfo, CONTRACT_INFO, IDX_OWNER, MINTER,
OPERATORS,
increment_tokens, num_tokens, tokens, Approval, TokenInfo, CONTRACT_INFO, MINTER, OPERATORS,
};
use cw_storage_plus::{Bound, OwnedBound};
use cw_storage_plus::Bound;

// version info for migration info
const CONTRACT_NAME: &str = "crates.io:cw721-base";
Expand Down Expand Up @@ -486,12 +485,12 @@ fn query_all_approvals<S: Storage, A: Api, Q: Querier>(
) -> StdResult<ApprovedForAllResponse> {
let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize;
let start_canon = maybe_canonical(deps.api, start_after)?;
let start = OwnedBound::exclusive(start_canon);
let start = start_canon.map(Bound::exclusive);

let owner_raw = deps.api.canonical_address(&owner)?;
let res: StdResult<Vec<_>> = OPERATORS
.prefix(&owner_raw)
.range(&deps.storage, start.bound(), Bound::None, Order::Ascending)
.range(&deps.storage, start, None, Order::Ascending)
.filter(|r| include_expired || r.is_err() || !r.as_ref().unwrap().1.is_expired(&env.block))
.take(limit)
.map(|item| parse_approval(deps.api, item))
Expand All @@ -514,12 +513,14 @@ fn query_tokens<S: Storage, A: Api, Q: Querier>(
) -> StdResult<TokensResponse> {
let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize;
// TODO: get pagination working on second indexes
let _start = OwnedBound::exclusive(start_after.map(Vec::from));
let _start = start_after.map(Bound::exclusive);

let owner_raw = deps.api.canonical_address(&owner)?;
let tokens: Result<Vec<String>, _> = tokens::<S>()
.pks_by_index(&deps.storage, IDX_OWNER, &owner_raw)?
// .range(&deps.storage, start.bound(), Bound::None, Order::Ascending)
.idx
.owner
.pks(&deps.storage, &owner_raw)
// .range(&deps.storage, start.bound(), None, Order::Ascending)
.take(limit)
.map(String::from_utf8)
.collect();
Expand All @@ -534,10 +535,10 @@ fn query_all_tokens<S: Storage, A: Api, Q: Querier>(
limit: Option<u32>,
) -> StdResult<TokensResponse> {
let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize;
let start = OwnedBound::exclusive(start_after.map(Vec::from));
let start = start_after.map(Bound::exclusive);

let tokens: StdResult<Vec<String>> = tokens::<S>()
.range(&deps.storage, start.bound(), Bound::None, Order::Ascending)
.range(&deps.storage, start, None, Order::Ascending)
.take(limit)
.map(|item| item.map(|(k, _)| String::from_utf8_lossy(&k).to_string()))
.collect();
Expand Down
23 changes: 16 additions & 7 deletions contracts/cw721-base/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};

use cosmwasm_std::{CanonicalAddr, StdResult, Storage};
use cw721::{ContractInfoResponse, Expiration};
use cw_storage_plus::{IndexedMap, Item, Map};
use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct TokenInfo {
Expand Down Expand Up @@ -45,11 +45,20 @@ pub fn increment_tokens<S: Storage>(storage: &mut S) -> StdResult<u64> {
Ok(val)
}

pub const IDX_OWNER: &str = "owner";
pub struct TokenIndexes<'a, S: Storage> {
pub owner: MultiIndex<'a, S, TokenInfo>,
}

impl<'a, S: Storage> IndexList<S, TokenInfo> for TokenIndexes<'a, S> {
fn get_indexes(&'_ self) -> Box<dyn Iterator<Item = &'_ dyn Index<S, TokenInfo>> + '_> {
let v: Vec<&dyn Index<S, TokenInfo>> = vec![&self.owner];
Box::new(v.into_iter())
}
}

// indexed map needs function, not const (for now at least)
pub fn tokens<'a, S: Storage + 'a>() -> IndexedMap<'a, 'a, &'a str, TokenInfo, S> {
IndexedMap::<&str, TokenInfo, S>::new(b"tokens")
.with_index(IDX_OWNER, b"tokens__owner", |d| d.owner.to_vec())
.unwrap()
pub fn tokens<'a, S: Storage>() -> IndexedMap<'a, &'a str, TokenInfo, S, TokenIndexes<'a, S>> {
let indexes = TokenIndexes {
owner: MultiIndex::new(|d| d.owner.to_vec(), b"tokens", b"tokens__owner"),
};
IndexedMap::new(b"tokens", indexes)
}
2 changes: 1 addition & 1 deletion packages/storage-plus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod prefix;

pub use endian::Endian;
#[cfg(feature = "iterator")]
pub use indexed_map::IndexedMap;
pub use indexed_map::{IndexList, IndexedMap};
#[cfg(feature = "iterator")]
pub use indexes::{index_int, index_string, Index, MultiIndex, UniqueIndex};
pub use item::Item;
Expand Down

0 comments on commit ae42b7d

Please sign in to comment.