Progress #166: Initial implementation of get_full_accounts API call

This commit is contained in:
Nathan Hourt 2015-07-16 17:02:08 -04:00
parent dc8849f23b
commit 723b11533b
5 changed files with 124 additions and 22 deletions

View file

@ -149,6 +149,87 @@ namespace graphene { namespace app {
return result;
}
std::map<std::string, fc::variant> database_api::get_full_accounts(std::function<void(const variant&)> callback,
const vector<std::string>& names_or_ids)
{
std::map<std::string, fc::variant> results;
std::set<object_id_type> ids_to_subscribe;
for (const std::string& account_name_or_id : names_or_ids)
{
const account_object* account = nullptr;
if (std::isdigit(account_name_or_id[0]))
account = _db.find(fc::variant(account_name_or_id).as<account_id_type>());
else
{
const auto& idx = _db.get_index_type<account_index>().indices().get<by_name>();
auto itr = idx.find(account_name_or_id);
if (itr != idx.end())
account = &*itr;
}
if (account == nullptr)
continue;
ids_to_subscribe.insert({account->id, account->statistics});
fc::mutable_variant_object full_account;
// Add the account itself, its statistics object, cashback balance, and referral account names
full_account("account", *account)("statistics", account->statistics(_db))
("registrar_name", account->registrar(_db).name)("referrer_name", account->referrer(_db).name)
("lifetime_referrer_name", account->lifetime_referrer(_db).name);
if (account->cashback_vb)
{
ids_to_subscribe.insert(*account->cashback_vb);
full_account("cashback_balance", account->cashback_balance(_db));
}
// Add the account's balances
auto balance_range = _db.get_index_type<account_balance_index>().indices().get<by_account>().equal_range(account->id);
vector<account_balance_object> balances;
std::for_each(balance_range.first, balance_range.second,
[&balances, &ids_to_subscribe](const account_balance_object& balance) {
balances.emplace_back(balance);
ids_to_subscribe.insert(balance.id);
});
idump((balances));
full_account("balances", balances);
// Add the account's vesting balances
auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>().equal_range(account->id);
vector<vesting_balance_object> vesting_balances;
std::for_each(vesting_range.first, vesting_range.second,
[&vesting_balances, &ids_to_subscribe](const vesting_balance_object& balance) {
vesting_balances.emplace_back(balance);
ids_to_subscribe.insert(balance.id);
});
full_account("vesting_balances", vesting_balances);
// Add the account's orders
auto order_range = _db.get_index_type<limit_order_index>().indices().get<by_account>().equal_range(account->id);
vector<limit_order_object> orders;
std::for_each(order_range.first, order_range.second,
[&orders, &ids_to_subscribe] (const limit_order_object& order) {
orders.emplace_back(order);
ids_to_subscribe.insert(order.id);
});
auto call_range = _db.get_index_type<call_order_index>().indices().get<by_account>().equal_range(account->id);
vector<call_order_object> calls;
std::for_each(call_range.first, call_range.second,
[&calls, &ids_to_subscribe] (const call_order_object& call) {
calls.emplace_back(call);
ids_to_subscribe.insert(call.id);
});
full_account("limit_orders", orders)("call_orders", calls);
results[account_name_or_id] = full_account;
}
wdump((results));
subscribe_to_objects(callback, vector<object_id_type>(ids_to_subscribe.begin(), ids_to_subscribe.end()));
return results;
}
vector<asset> database_api::get_account_balances(account_id_type acnt, const flat_set<asset_id_type>& assets)const
{
vector<asset> result;

View file

@ -57,29 +57,29 @@ namespace graphene { namespace app {
*
* If any of the provided IDs does not map to an object, a null variant is returned in its position.
*/
fc::variants get_objects(const vector<object_id_type>& ids)const;
fc::variants get_objects(const vector<object_id_type>& ids)const;
/**
* @brief Retrieve a block header
* @param block_num Height of the block whose header should be returned
* @return header of the referenced block, or null if no matching block was found
*/
optional<block_header> get_block_header(uint32_t block_num)const;
optional<block_header> get_block_header(uint32_t block_num)const;
/**
* @brief Retrieve a full, signed block
* @param block_num Height of the block to be returned
* @return the referenced block, or null if no matching block was found
*/
optional<signed_block> get_block(uint32_t block_num)const;
optional<signed_block> get_block(uint32_t block_num)const;
/**
* @brief used to fetch an individual transaction.
*/
processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const;
processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const;
/**
* @brief Retrieve the current @ref global_property_object
*/
global_property_object get_global_properties()const;
global_property_object get_global_properties()const;
/**
* @brief Retrieve the current @ref dynamic_global_property_object
*/
@ -138,6 +138,21 @@ namespace graphene { namespace app {
*/
map<string,account_id_type> lookup_accounts(const string& lower_bound_name, uint32_t limit)const;
/**
* @brief Fetch all objects relevant to the specified accounts and subscribe to updates
* @param callback Function to call with updates
* @param names_or_ids Each item must be the name or ID of an account to retrieve
* @return Map of string from @ref names_or_ids to the corresponding account
*
* This function fetches all relevant objects for the given accounts, and subscribes to updates to the given
* accounts. If any of the strings in @ref names_or_ids cannot be tied to an account, that input will be
* ignored. All other accounts will be retrieved and subscribed.
*
* TODO: Describe the return value and argument to callback in detail
*/
std::map<string,fc::variant> get_full_accounts(std::function<void(const variant&)> callback,
const vector<string>& names_or_ids);
/**
* @brief Get limit orders in a given market
* @param a ID of asset being sold
@ -324,9 +339,9 @@ namespace graphene { namespace app {
vector<bucket_object> get_market_history( asset_id_type a, asset_id_type b, uint32_t bucket_seconds,
fc::time_point_sec start, fc::time_point_sec end )const;
flat_set<uint32_t> get_market_history_buckets()const;
flat_set<uint32_t> get_market_history_buckets()const;
private:
application& _app;
application& _app;
};
/**
@ -403,7 +418,7 @@ namespace graphene { namespace app {
std::vector<net::peer_status> get_connected_peers() const;
private:
application& _app;
application& _app;
};
/**
@ -440,7 +455,7 @@ namespace graphene { namespace app {
/// @brief Called to enable an API, not reflected.
void enable_api( const string& api_name );
application& _app;
application& _app;
optional< fc::api<database_api> > _database_api;
optional< fc::api<network_broadcast_api> > _network_broadcast_api;
optional< fc::api<network_node_api> > _network_node_api;
@ -464,6 +479,7 @@ FC_API(graphene::app::database_api,
(lookup_account_names)
(get_account_count)
(lookup_accounts)
(get_full_accounts)
(get_account_balances)
(get_named_account_balances)
(lookup_asset_symbols)

View file

@ -174,8 +174,7 @@ void database::initialize_indexes()
prop_index->add_secondary_index<required_approval_index>();
add_index< primary_index<withdraw_permission_index > >();
//add_index< primary_index<vesting_balance_index> >();
add_index< primary_index<simple_index<vesting_balance_object>> >();
add_index< primary_index<vesting_balance_index> >();
add_index< primary_index<worker_index> >();
add_index< primary_index<balance_index> >();

View file

@ -34,6 +34,7 @@ namespace graphene { namespace chain {
struct by_id;
struct by_price;
struct by_expiration;
struct by_account;
typedef multi_index_container<
limit_order_object,
indexed_by<
@ -46,7 +47,8 @@ namespace graphene { namespace chain {
member< object, object_id_type, &object::id>
>,
composite_key_compare< std::greater<price>, std::less<object_id_type> >
>
>,
ordered_non_unique< tag<by_account>, member<limit_order_object, account_id_type, &limit_order_object::seller>>
>
> limit_order_multi_index_type;

View file

@ -159,10 +159,14 @@ namespace graphene { namespace chain {
/**
* @ingroup object_index
*/
struct by_account;
typedef multi_index_container<
vesting_balance_object,
indexed_by<
hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >
hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_non_unique< tag<by_account>,
member<vesting_balance_object, account_id_type, &vesting_balance_object::owner>
>
>
> vesting_balance_multi_index_type;
/**