diff --git a/libraries/plugins/apis/database_api/database_api.cpp b/libraries/plugins/apis/database_api/database_api.cpp index 7d04744304..cb42bb07b7 100644 --- a/libraries/plugins/apis/database_api/database_api.cpp +++ b/libraries/plugins/apis/database_api/database_api.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -17,7 +18,11 @@ namespace steem { namespace plugins { namespace database_api { +using namespace util; +//using util::iterate_results; +//using util::filter_default; +//using util::on_push_default; class database_api_impl { @@ -88,50 +93,6 @@ class database_api_impl (find_smt_token_balances) ) - template< typename ResultType > - static ResultType on_push_default( const ResultType& r ) { return r; } - - template< typename ValueType > - static bool filter_default( const ValueType& r ) { return true; } - - template - void iterate_results( - StartType start, - std::vector& result, - uint32_t limit, - OnPushType&& on_push, - FilterType&& filter, - order_direction_type direction = ascending ) - { - const auto& idx = _db.get_index< IndexType, OrderType >(); - if( direction == ascending ) - { - auto itr = idx.lower_bound( start ); - auto end = idx.end(); - - while( result.size() < limit && itr != end ) - { - if( filter( *itr ) ) - result.push_back( on_push( *itr ) ); - - ++itr; - } - } - else if( direction == descending ) - { - auto itr = boost::make_reverse_iterator( idx.lower_bound( start ) ); - auto end = idx.rend(); - - while( result.size() < limit && itr != end ) - { - if( filter( *itr ) ) - result.push_back( on_push( *itr ) ); - - ++itr; - } - } - } - chain::database& _db; }; @@ -236,35 +197,38 @@ DEFINE_API_IMPL( database_api_impl, list_witnesses ) { case( by_name ): { - iterate_results< chain::witness_index, chain::by_name >( + iterate_results( + _db.get_index< chain::witness_index, chain::by_name >(), args.start.as< protocol::account_name_type >(), result.witnesses, args.limit, [&]( const witness_object& w ){ return api_witness_object( w ); }, - &database_api_impl::filter_default< witness_object > ); + &filter_default< witness_object > ); break; } case( by_vote_name ): { auto key = args.start.as< std::pair< share_type, account_name_type > >(); - iterate_results< chain::witness_index, chain::by_vote_name >( + iterate_results( + _db.get_index< chain::witness_index, chain::by_vote_name >(), boost::make_tuple( key.first, key.second ), result.witnesses, args.limit, [&]( const witness_object& w ){ return api_witness_object( w ); }, - &database_api_impl::filter_default< witness_object > ); + &filter_default< witness_object > ); break; } case( by_schedule_time ): { auto key = args.start.as< std::pair< fc::uint128, account_name_type > >(); auto wit_id = _db.get< chain::witness_object, chain::by_name >( key.second ).id; - iterate_results< chain::witness_index, chain::by_schedule_time >( + iterate_results( + _db.get_index< chain::witness_index, chain::by_schedule_time >(), boost::make_tuple( key.first, wit_id ), result.witnesses, args.limit, [&]( const witness_object& w ){ return api_witness_object( w ); }, - &database_api_impl::filter_default< witness_object > ); + &filter_default< witness_object > ); break; } default: @@ -303,23 +267,25 @@ DEFINE_API_IMPL( database_api_impl, list_witness_votes ) case( by_account_witness ): { auto key = args.start.as< std::pair< account_name_type, account_name_type > >(); - iterate_results< chain::witness_vote_index, chain::by_account_witness >( + iterate_results( + _db.get_index< chain::witness_vote_index, chain::by_account_witness >(), boost::make_tuple( key.first, key.second ), result.votes, args.limit, [&]( const witness_vote_object& v ){ return api_witness_vote_object( v ); }, - &database_api_impl::filter_default< api_witness_vote_object > ); + &filter_default< api_witness_vote_object > ); break; } case( by_witness_account ): { auto key = args.start.as< std::pair< account_name_type, account_name_type > >(); - iterate_results< chain::witness_vote_index, chain::by_witness_account >( + iterate_results( + _db.get_index< chain::witness_vote_index, chain::by_witness_account >(), boost::make_tuple( key.first, key.second ), result.votes, args.limit, [&]( const witness_vote_object& v ){ return api_witness_vote_object( v ); }, - &database_api_impl::filter_default< api_witness_vote_object > ); + &filter_default< api_witness_vote_object > ); break; } default: @@ -360,34 +326,37 @@ DEFINE_API_IMPL( database_api_impl, list_accounts ) { case( by_name ): { - iterate_results< chain::account_index, chain::by_name >( + iterate_results( + _db.get_index< chain::account_index, chain::by_name >(), args.start.as< protocol::account_name_type >(), result.accounts, args.limit, [&]( const account_object& a ){ return api_account_object( a, _db ); }, - &database_api_impl::filter_default< account_object > ); + &filter_default< account_object > ); break; } case( by_proxy ): { auto key = args.start.as< std::pair< account_name_type, account_name_type > >(); - iterate_results< chain::account_index, chain::by_proxy >( + iterate_results( + _db.get_index< chain::account_index, chain::by_proxy >(), boost::make_tuple( key.first, key.second ), result.accounts, args.limit, [&]( const account_object& a ){ return api_account_object( a, _db ); }, - &database_api_impl::filter_default< account_object > ); + &filter_default< account_object > ); break; } case( by_next_vesting_withdrawal ): { auto key = args.start.as< std::pair< fc::time_point_sec, account_name_type > >(); - iterate_results< chain::account_index, chain::by_next_vesting_withdrawal >( + iterate_results( + _db.get_index< chain::account_index, chain::by_next_vesting_withdrawal >(), boost::make_tuple( key.first, key.second ), result.accounts, args.limit, [&]( const account_object& a ){ return api_account_object( a, _db ); }, - &database_api_impl::filter_default< account_object > ); + &filter_default< account_object > ); break; } default: @@ -423,12 +392,13 @@ DEFINE_API_IMPL( database_api_impl, list_owner_histories ) result.owner_auths.reserve( args.limit ); auto key = args.start.as< std::pair< account_name_type, fc::time_point_sec > >(); - iterate_results< chain::owner_authority_history_index, chain::by_account >( + iterate_results( + _db.get_index< chain::owner_authority_history_index, chain::by_account >(), boost::make_tuple( key.first, key.second ), result.owner_auths, args.limit, [&]( const owner_authority_history_object& o ){ return api_owner_authority_history_object( o ); }, - &database_api_impl::filter_default< owner_authority_history_object > ); + &filter_default< owner_authority_history_object > ); return result; } @@ -463,23 +433,25 @@ DEFINE_API_IMPL( database_api_impl, list_account_recovery_requests ) { case( by_account ): { - iterate_results< chain::account_recovery_request_index, chain::by_account >( + iterate_results( + _db.get_index< chain::account_recovery_request_index, chain::by_account >(), args.start.as< account_name_type >(), result.requests, args.limit, [&]( const account_recovery_request_object& a ){ return api_account_recovery_request_object( a ); }, - &database_api_impl::filter_default< api_account_recovery_request_object > ); + &filter_default< api_account_recovery_request_object > ); break; } case( by_expiration ): { auto key = args.start.as< std::pair< fc::time_point_sec, account_name_type > >(); - iterate_results< chain::account_recovery_request_index, chain::by_expiration >( + iterate_results( + _db.get_index< chain::account_recovery_request_index, chain::by_expiration >(), boost::make_tuple( key.first, key.second ), result.requests, args.limit, [&]( const account_recovery_request_object& a ){ return api_account_recovery_request_object( a ); }, - &database_api_impl::filter_default< api_account_recovery_request_object > ); + &filter_default< api_account_recovery_request_object > ); break; } default: @@ -519,23 +491,25 @@ DEFINE_API_IMPL( database_api_impl, list_change_recovery_account_requests ) { case( by_account ): { - iterate_results< chain::change_recovery_account_request_index, chain::by_account >( + iterate_results( + _db.get_index< chain::change_recovery_account_request_index, chain::by_account >(), args.start.as< account_name_type >(), result.requests, args.limit, - &database_api_impl::on_push_default< change_recovery_account_request_object >, - &database_api_impl::filter_default< change_recovery_account_request_object > ); + &on_push_default< change_recovery_account_request_object >, + &filter_default< change_recovery_account_request_object > ); break; } case( by_effective_date ): { auto key = args.start.as< std::pair< fc::time_point_sec, account_name_type > >(); - iterate_results< chain::change_recovery_account_request_index, chain::by_effective_date >( + iterate_results( + _db.get_index< chain::change_recovery_account_request_index, chain::by_effective_date >(), boost::make_tuple( key.first, key.second ), result.requests, args.limit, - &database_api_impl::on_push_default< change_recovery_account_request_object >, - &database_api_impl::filter_default< change_recovery_account_request_object > ); + &on_push_default< change_recovery_account_request_object >, + &filter_default< change_recovery_account_request_object > ); break; } default: @@ -576,24 +550,26 @@ DEFINE_API_IMPL( database_api_impl, list_escrows ) case( by_from_id ): { auto key = args.start.as< std::pair< account_name_type, uint32_t > >(); - iterate_results< chain::escrow_index, chain::by_from_id >( + iterate_results( + _db.get_index< chain::escrow_index, chain::by_from_id >(), boost::make_tuple( key.first, key.second ), result.escrows, args.limit, - &database_api_impl::on_push_default< escrow_object >, - &database_api_impl::filter_default< escrow_object > ); + &on_push_default< escrow_object >, + &filter_default< escrow_object > ); break; } case( by_ratification_deadline ): { auto key = args.start.as< std::vector< fc::variant > >(); FC_ASSERT( key.size() == 3, "by_ratification_deadline start requires 3 values. (bool, time_point_sec, escrow_id_type)" ); - iterate_results< chain::escrow_index, chain::by_ratification_deadline >( + iterate_results( + _db.get_index< chain::escrow_index, chain::by_ratification_deadline >(), boost::make_tuple( key[0].as< bool >(), key[1].as< fc::time_point_sec >(), key[2].as< escrow_id_type >() ), result.escrows, args.limit, - &database_api_impl::on_push_default< escrow_object >, - &database_api_impl::filter_default< escrow_object > ); + &on_push_default< escrow_object >, + &filter_default< escrow_object > ); break; } default: @@ -634,23 +610,25 @@ DEFINE_API_IMPL( database_api_impl, list_withdraw_vesting_routes ) case( by_withdraw_route ): { auto key = args.start.as< std::pair< account_name_type, account_name_type > >(); - iterate_results< chain::withdraw_vesting_route_index, chain::by_withdraw_route >( + iterate_results( + _db.get_index< chain::withdraw_vesting_route_index, chain::by_withdraw_route >(), boost::make_tuple( key.first, key.second ), result.routes, args.limit, - &database_api_impl::on_push_default< withdraw_vesting_route_object >, - &database_api_impl::filter_default< withdraw_vesting_route_object > ); + &on_push_default< withdraw_vesting_route_object >, + &filter_default< withdraw_vesting_route_object > ); break; } case( by_destination ): { auto key = args.start.as< std::pair< account_name_type, withdraw_vesting_route_id_type > >(); - iterate_results< chain::withdraw_vesting_route_index, chain::by_destination >( + iterate_results( + _db.get_index< chain::withdraw_vesting_route_index, chain::by_destination >(), boost::make_tuple( key.first, key.second ), result.routes, args.limit, - &database_api_impl::on_push_default< withdraw_vesting_route_object >, - &database_api_impl::filter_default< withdraw_vesting_route_object > ); + &on_push_default< withdraw_vesting_route_object >, + &filter_default< withdraw_vesting_route_object > ); break; } default: @@ -714,36 +692,39 @@ DEFINE_API_IMPL( database_api_impl, list_savings_withdrawals ) case( by_from_id ): { auto key = args.start.as< std::pair< account_name_type, uint32_t > >(); - iterate_results< chain::savings_withdraw_index, chain::by_from_rid >( + iterate_results( + _db.get_index< chain::savings_withdraw_index, chain::by_from_rid >(), boost::make_tuple( key.first, key.second ), result.withdrawals, args.limit, [&]( const savings_withdraw_object& w ){ return api_savings_withdraw_object( w ); }, - &database_api_impl::filter_default< savings_withdraw_object > ); + &filter_default< savings_withdraw_object > ); break; } case( by_complete_from_id ): { auto key = args.start.as< std::vector< fc::variant > >(); FC_ASSERT( key.size() == 3, "by_complete_from_id start requires 3 values. (time_point_sec, account_name_type, uint32_t)" ); - iterate_results< chain::savings_withdraw_index, chain::by_complete_from_rid >( + iterate_results( + _db.get_index< chain::savings_withdraw_index, chain::by_complete_from_rid >(), boost::make_tuple( key[0].as< fc::time_point_sec >(), key[1].as< account_name_type >(), key[2].as< uint32_t >() ), result.withdrawals, args.limit, [&]( const savings_withdraw_object& w ){ return api_savings_withdraw_object( w ); }, - &database_api_impl::filter_default< savings_withdraw_object > ); + &filter_default< savings_withdraw_object > ); break; } case( by_to_complete ): { auto key = args.start.as< std::vector< fc::variant > >(); FC_ASSERT( key.size() == 3, "by_to_complete start requires 3 values. (account_name_type, time_point_sec, savings_withdraw_id_type" ); - iterate_results< chain::savings_withdraw_index, chain::by_to_complete >( + iterate_results( + _db.get_index< chain::savings_withdraw_index, chain::by_to_complete >(), boost::make_tuple( key[0].as< account_name_type >(), key[1].as< fc::time_point_sec >(), key[2].as< savings_withdraw_id_type >() ), result.withdrawals, args.limit, [&]( const savings_withdraw_object& w ){ return api_savings_withdraw_object( w ); }, - &database_api_impl::filter_default< savings_withdraw_object > ); + &filter_default< savings_withdraw_object > ); break; } default: @@ -783,12 +764,13 @@ DEFINE_API_IMPL( database_api_impl, list_vesting_delegations ) case( by_delegation ): { auto key = args.start.as< std::pair< account_name_type, account_name_type > >(); - iterate_results< chain::vesting_delegation_index, chain::by_delegation >( + iterate_results( + _db.get_index< chain::vesting_delegation_index, chain::by_delegation >(), boost::make_tuple( key.first, key.second ), result.delegations, args.limit, - &database_api_impl::on_push_default< api_vesting_delegation_object >, - &database_api_impl::filter_default< vesting_delegation_object > ); + &on_push_default< api_vesting_delegation_object >, + &filter_default< vesting_delegation_object > ); break; } default: @@ -828,24 +810,26 @@ DEFINE_API_IMPL( database_api_impl, list_vesting_delegation_expirations ) case( by_expiration ): { auto key = args.start.as< std::pair< time_point_sec, vesting_delegation_expiration_id_type > >(); - iterate_results< chain::vesting_delegation_expiration_index, chain::by_expiration >( + iterate_results( + _db.get_index< chain::vesting_delegation_expiration_index, chain::by_expiration >(), boost::make_tuple( key.first, key.second ), result.delegations, args.limit, - &database_api_impl::on_push_default< api_vesting_delegation_expiration_object >, - &database_api_impl::filter_default< vesting_delegation_expiration_object > ); + &on_push_default< api_vesting_delegation_expiration_object >, + &filter_default< vesting_delegation_expiration_object > ); break; } case( by_account_expiration ): { auto key = args.start.as< std::vector< fc::variant > >(); FC_ASSERT( key.size() == 3, "by_account_expiration start requires 3 values. (account_name_type, time_point_sec, vesting_delegation_expiration_id_type" ); - iterate_results< chain::vesting_delegation_expiration_index, chain::by_account_expiration >( + iterate_results( + _db.get_index< chain::vesting_delegation_expiration_index, chain::by_account_expiration >(), boost::make_tuple( key[0].as< account_name_type >(), key[1].as< time_point_sec >(), key[2].as< vesting_delegation_expiration_id_type >() ), result.delegations, args.limit, - &database_api_impl::on_push_default< api_vesting_delegation_expiration_object >, - &database_api_impl::filter_default< vesting_delegation_expiration_object > ); + &on_push_default< api_vesting_delegation_expiration_object >, + &filter_default< vesting_delegation_expiration_object > ); break; } default: @@ -885,23 +869,25 @@ DEFINE_API_IMPL( database_api_impl, list_sbd_conversion_requests ) case( by_conversion_date ): { auto key = args.start.as< std::pair< time_point_sec, convert_request_id_type > >(); - iterate_results< chain::convert_request_index, chain::by_conversion_date >( + iterate_results( + _db.get_index< chain::convert_request_index, chain::by_conversion_date >(), boost::make_tuple( key.first, key.second ), result.requests, args.limit, - &database_api_impl::on_push_default< api_convert_request_object >, - &database_api_impl::filter_default< convert_request_object > ); + &on_push_default< api_convert_request_object >, + &filter_default< convert_request_object > ); break; } case( by_account ): { auto key = args.start.as< std::pair< account_name_type, uint32_t > >(); - iterate_results< chain::convert_request_index, chain::by_owner >( + iterate_results( + _db.get_index< chain::convert_request_index, chain::by_owner >(), boost::make_tuple( key.first, key.second ), result.requests, args.limit, - &database_api_impl::on_push_default< api_convert_request_object >, - &database_api_impl::filter_default< convert_request_object > ); + &on_push_default< api_convert_request_object >, + &filter_default< convert_request_object > ); break; } default: @@ -940,23 +926,25 @@ DEFINE_API_IMPL( database_api_impl, list_decline_voting_rights_requests ) { case( by_account ): { - iterate_results< chain::decline_voting_rights_request_index, chain::by_account >( + iterate_results( + _db.get_index< chain::decline_voting_rights_request_index, chain::by_account >(), args.start.as< account_name_type >(), result.requests, args.limit, - &database_api_impl::on_push_default< api_decline_voting_rights_request_object >, - &database_api_impl::filter_default< decline_voting_rights_request_object > ); + &on_push_default< api_decline_voting_rights_request_object >, + &filter_default< decline_voting_rights_request_object > ); break; } case( by_effective_date ): { auto key = args.start.as< std::pair< time_point_sec, account_name_type > >(); - iterate_results< chain::decline_voting_rights_request_index, chain::by_effective_date >( + iterate_results( + _db.get_index< chain::decline_voting_rights_request_index, chain::by_effective_date >(), boost::make_tuple( key.first, key.second ), result.requests, args.limit, - &database_api_impl::on_push_default< api_decline_voting_rights_request_object >, - &database_api_impl::filter_default< decline_voting_rights_request_object > ); + &on_push_default< api_decline_voting_rights_request_object >, + &filter_default< decline_voting_rights_request_object > ); break; } default: @@ -1016,23 +1004,25 @@ DEFINE_API_IMPL( database_api_impl, list_comments ) comment_id = comment->id; } - iterate_results< chain::comment_index, chain::by_cashout_time >( + iterate_results( + _db.get_index< chain::comment_index, chain::by_cashout_time >(), boost::make_tuple( key[0].as< fc::time_point_sec >(), comment_id ), result.comments, args.limit, [&]( const comment_object& c ){ return api_comment_object( c, _db ); }, - &database_api_impl::filter_default< comment_object > ); + &filter_default< comment_object > ); break; } case( by_permlink ): { auto key = args.start.as< std::pair< account_name_type, string > >(); - iterate_results< chain::comment_index, chain::by_permlink >( + iterate_results( + _db.get_index< chain::comment_index, chain::by_permlink >(), boost::make_tuple( key.first, key.second ), result.comments, args.limit, [&]( const comment_object& c ){ return api_comment_object( c, _db ); }, - &database_api_impl::filter_default< comment_object > ); + &filter_default< comment_object > ); break; } case( by_root ): @@ -1062,12 +1052,13 @@ DEFINE_API_IMPL( database_api_impl, list_comments ) child_id = child->id; } - iterate_results< chain::comment_index, chain::by_root >( + iterate_results( + _db.get_index< chain::comment_index, chain::by_root >(), boost::make_tuple( root_id, child_id ), result.comments, args.limit, [&]( const comment_object& c ){ return api_comment_object( c, _db ); }, - &database_api_impl::filter_default< comment_object > ); + &filter_default< comment_object > ); break; } case( by_parent ): @@ -1086,12 +1077,13 @@ DEFINE_API_IMPL( database_api_impl, list_comments ) child_id = child->id; } - iterate_results< chain::comment_index, chain::by_parent >( + iterate_results( + _db.get_index< chain::comment_index, chain::by_parent >(), boost::make_tuple( key[0].as< account_name_type >(), key[1].as< string >(), child_id ), result.comments, args.limit, [&]( const comment_object& c ){ return api_comment_object( c, _db ); }, - &database_api_impl::filter_default< comment_object > ); + &filter_default< comment_object > ); break; } #ifndef IS_LOW_MEM @@ -1111,12 +1103,13 @@ DEFINE_API_IMPL( database_api_impl, list_comments ) child_id = child->id; } - iterate_results< chain::comment_index, chain::by_last_update >( + iterate_results( + _db.get_index< chain::comment_index, chain::by_last_update >(), boost::make_tuple( key[0].as< account_name_type >(), key[1].as< fc::time_point_sec >(), child_id ), result.comments, args.limit, [&]( const comment_object& c ){ return api_comment_object( c, _db ); }, - &database_api_impl::filter_default< comment_object > ); + &filter_default< comment_object > ); break; } case( by_author_last_update ): @@ -1135,12 +1128,13 @@ DEFINE_API_IMPL( database_api_impl, list_comments ) comment_id = comment->id; } - iterate_results< chain::comment_index, chain::by_last_update >( + iterate_results( + _db.get_index< chain::comment_index, chain::by_last_update >(), boost::make_tuple( key[0].as< account_name_type >(), key[1].as< fc::time_point_sec >(), comment_id ), result.comments, args.limit, [&]( const comment_object& c ){ return api_comment_object( c, _db ); }, - &database_api_impl::filter_default< comment_object > ); + &filter_default< comment_object > ); break; } #endif @@ -1225,21 +1219,23 @@ namespace last_votes_misc if( SORTORDERTYPE == by_comment_voter_symbol ) { - _impl.iterate_results< chain::comment_vote_index, chain::by_comment_voter_symbol >( - boost::make_tuple( comment_id, voter_id ), - c, - limit, - [&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _impl._db ); }, - &database_api_impl::filter_default< comment_vote_object > ); + iterate_results( + _impl._db.get_index< chain::comment_vote_index, chain::by_comment_voter_symbol >(), + boost::make_tuple( comment_id, voter_id ), + c, + limit, + [&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _impl._db ); }, + &filter_default< comment_vote_object > ); } else if( SORTORDERTYPE == by_voter_comment ) { - _impl.iterate_results< chain::comment_vote_index, chain::by_voter_comment_symbol >( - boost::make_tuple( voter_id, comment_id ), - c, - limit, - [&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _impl._db ); }, - &database_api_impl::filter_default< comment_vote_object > ); + iterate_results( + _impl._db.get_index< chain::comment_vote_index, chain::by_voter_comment_symbol >(), + boost::make_tuple( voter_id, comment_id ), + c, + limit, + [&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _impl._db ); }, + &filter_default< comment_vote_object > ); } } @@ -1305,12 +1301,13 @@ DEFINE_API_IMPL( database_api_impl, list_votes ) } } - iterate_results< chain::comment_vote_index, chain::by_comment_symbol_voter >( + iterate_results( + _db.get_index< chain::comment_vote_index, chain::by_comment_symbol_voter >(), boost::make_tuple( comment_id, start_symbol, voter_id ), result.votes, args.limit, [&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _db ); }, - &database_api_impl::filter_default< comment_vote_object > ); + &filter_default< comment_vote_object > ); break; } case( by_voter_symbol_comment ): @@ -1345,12 +1342,13 @@ DEFINE_API_IMPL( database_api_impl, list_votes ) } } - iterate_results< chain::comment_vote_index, chain::by_voter_symbol_comment >( + iterate_results( + _db.get_index< chain::comment_vote_index, chain::by_voter_symbol_comment >(), boost::make_tuple( voter_id, start_symbol, comment_id ), result.votes, args.limit, [&]( const comment_vote_object& cv ){ return api_comment_vote_object( cv, _db ); }, - &database_api_impl::filter_default< comment_vote_object > ); + &filter_default< comment_vote_object > ); break; } default: @@ -1400,23 +1398,25 @@ DEFINE_API_IMPL( database_api_impl, list_limit_orders ) case( by_price ): { auto key = args.start.as< std::pair< price, limit_order_id_type > >(); - iterate_results< chain::limit_order_index, chain::by_price >( + iterate_results( + _db.get_index< chain::limit_order_index, chain::by_price >(), boost::make_tuple( key.first, key.second ), result.orders, args.limit, - &database_api_impl::on_push_default< api_limit_order_object >, - &database_api_impl::filter_default< limit_order_object > ); + &on_push_default< api_limit_order_object >, + &filter_default< limit_order_object > ); break; } case( by_account ): { auto key = args.start.as< std::pair< account_name_type, uint32_t > >(); - iterate_results< chain::limit_order_index, chain::by_account >( + iterate_results( + _db.get_index< chain::limit_order_index, chain::by_account >(), boost::make_tuple( key.first, key.second ), result.orders, args.limit, - &database_api_impl::on_push_default< api_limit_order_object >, - &database_api_impl::filter_default< limit_order_object > ); + &on_push_default< api_limit_order_object >, + &filter_default< limit_order_object > ); break; } default: @@ -1552,52 +1552,56 @@ DEFINE_API_IMPL( database_api_impl, list_proposals ) case by_creator: { auto key = args.start.as< std::pair< account_name_type, api_id_type > >(); - iterate_results< steem::chain::proposal_index, steem::chain::by_creator >( + iterate_results( + _db.get_index< steem::chain::proposal_index, steem::chain::by_creator >(), boost::make_tuple( key.first, key.second ), result.proposals, args.limit, [&]( const proposal_object& po ){ return api_proposal_object( po, current_time ); }, [&]( const proposal_object& po ){ return filter_proposal_status( po, args.status, current_time ); }, - args.order_direction + args.order_direction == ascending ); break; } case by_start_date: { auto key = args.start.as< std::pair< time_point_sec, api_id_type > >(); - iterate_results< steem::chain::proposal_index, steem::chain::by_start_date >( + iterate_results( + _db.get_index< steem::chain::proposal_index, steem::chain::by_start_date >(), boost::make_tuple( key.first, key.second ), result.proposals, args.limit, [&]( const proposal_object& po ){ return api_proposal_object( po, current_time ); }, [&]( const proposal_object& po ){ return filter_proposal_status( po, args.status, current_time ); }, - args.order_direction + args.order_direction == ascending ); break; } case by_end_date: { auto key = args.start.as< std::pair< time_point_sec, api_id_type > >(); - iterate_results< steem::chain::proposal_index, steem::chain::by_end_date >( + iterate_results( + _db.get_index< steem::chain::proposal_index, steem::chain::by_end_date >(), boost::make_tuple( key.first, key.second ), result.proposals, args.limit, [&]( const proposal_object& po ){ return api_proposal_object( po, current_time ); }, [&]( const proposal_object& po ){ return filter_proposal_status( po, args.status, current_time ); }, - args.order_direction + args.order_direction == ascending ); break; } case by_total_votes: { auto key = args.start.as< std::pair< uint64_t, api_id_type > >(); - iterate_results< steem::chain::proposal_index, steem::chain::by_total_votes >( + iterate_results( + _db.get_index< steem::chain::proposal_index, steem::chain::by_total_votes >(), boost::make_tuple( key.first, key.second ), result.proposals, args.limit, [&]( const proposal_object& po ){ return api_proposal_object( po, current_time ); }, [&]( const proposal_object& po ){ return filter_proposal_status( po, args.status, current_time ); }, - args.order_direction + args.order_direction == ascending ); break; } @@ -1646,7 +1650,8 @@ DEFINE_API_IMPL( database_api_impl, list_proposal_votes ) case by_voter_proposal: { auto key = args.start.as< std::pair< account_name_type, api_id_type > >(); - iterate_results< steem::chain::proposal_vote_index, steem::chain::by_voter_proposal >( + iterate_results( + _db.get_index< steem::chain::proposal_vote_index, steem::chain::by_voter_proposal >(), boost::make_tuple( key.first, key.second ), result.proposal_votes, args.limit, @@ -1656,14 +1661,15 @@ DEFINE_API_IMPL( database_api_impl, list_proposal_votes ) auto itr = _db.find< steem::chain::proposal_object, steem::chain::by_id >( po.proposal_id ); return itr != nullptr && !itr->removed; }, - args.order_direction + args.order_direction == ascending ); break; } case by_proposal_voter: { auto key = args.start.as< std::pair< api_id_type, account_name_type > >(); - iterate_results< steem::chain::proposal_vote_index, steem::chain::by_proposal_voter >( + iterate_results( + _db.get_index< steem::chain::proposal_vote_index, steem::chain::by_proposal_voter >(), boost::make_tuple( key.first, key.second ), result.proposal_votes, args.limit, @@ -1673,7 +1679,7 @@ DEFINE_API_IMPL( database_api_impl, list_proposal_votes ) auto itr = _db.find< steem::chain::proposal_object, steem::chain::by_id >( po.proposal_id ); return itr != nullptr && !itr->removed; }, - args.order_direction + args.order_direction == ascending ); break; } @@ -1852,12 +1858,13 @@ DEFINE_API_IMPL( database_api_impl, list_smt_contributions ) else start = boost::make_tuple( key[ 0 ].as< asset_symbol_type >(), key[ 1 ].as< account_name_type >(), key[ 2 ].as< uint32_t >() ); - iterate_results< chain::smt_contribution_index, chain::by_symbol_contributor >( + iterate_results( + _db.get_index< chain::smt_contribution_index, chain::by_symbol_contributor >(), start, result.contributions, args.limit, - &database_api_impl::on_push_default< chain::smt_contribution_object >, - &database_api_impl::filter_default< chain::smt_contribution_object > ); + &on_push_default< chain::smt_contribution_object >, + &filter_default< chain::smt_contribution_object > ); break; } case( by_symbol_id ): @@ -1871,12 +1878,13 @@ DEFINE_API_IMPL( database_api_impl, list_smt_contributions ) else start = boost::make_tuple( key[ 0 ].as< asset_symbol_type >(), key[ 1 ].as< smt_contribution_object_id_type >() ); - iterate_results< chain::smt_contribution_index, chain::by_symbol_id >( + iterate_results( + _db.get_index< chain::smt_contribution_index, chain::by_symbol_id >(), start, result.contributions, args.limit, - &database_api_impl::on_push_default< chain::smt_contribution_object >, - &database_api_impl::filter_default< chain::smt_contribution_object > ); + &on_push_default< chain::smt_contribution_object >, + &filter_default< chain::smt_contribution_object > ); break; } #ifndef IS_LOW_MEM @@ -1891,12 +1899,13 @@ DEFINE_API_IMPL( database_api_impl, list_smt_contributions ) else start = boost::make_tuple( key[ 0 ].as< account_name_type >(), key[ 1 ].as< asset_symbol_type >(), key[ 2 ].as< uint32_t >() ); - iterate_results< chain::smt_contribution_index, chain::by_contributor >( + iterate_results( + _db.get_index< chain::smt_contribution_index, chain::by_contributor >(), start, result.contributions, args.limit, - &database_api_impl::on_push_default< chain::smt_contribution_object >, - &database_api_impl::filter_default< chain::smt_contribution_object > ); + &on_push_default< chain::smt_contribution_object >, + &filter_default< chain::smt_contribution_object > ); break; } #endif @@ -1944,12 +1953,13 @@ DEFINE_API_IMPL( database_api_impl, list_smt_tokens ) start = asset_symbol_type::from_asset_num( args.start.as< asset_symbol_type >().get_stripped_precision_smt_num() ); } - iterate_results< chain::smt_token_index, chain::by_stripped_symbol >( + iterate_results( + _db.get_index< chain::smt_token_index, chain::by_stripped_symbol >(), start, result.tokens, args.limit, [&]( const smt_token_object& t ) { return api_smt_token_object( t, _db ); }, - &database_api_impl::filter_default< chain::smt_token_object > ); + &filter_default< chain::smt_token_object > ); break; } @@ -1969,12 +1979,13 @@ DEFINE_API_IMPL( database_api_impl, list_smt_tokens ) start = boost::make_tuple( key[0].as< account_name_type >(), key[1].as< asset_symbol_type >() ); } - iterate_results< chain::smt_token_index, chain::by_control_account >( + iterate_results( + _db.get_index< chain::smt_token_index, chain::by_control_account >(), start, result.tokens, args.limit, [&]( const smt_token_object& t ) { return api_smt_token_object( t, _db ); }, - &database_api_impl::filter_default< chain::smt_token_object > ); + &filter_default< chain::smt_token_object > ); break; } @@ -2024,12 +2035,13 @@ DEFINE_API_IMPL( database_api_impl, list_smt_token_emissions ) else start = boost::make_tuple( key[ 0 ].as< asset_symbol_type >(), key[ 1 ].as< time_point_sec >() ); - iterate_results< chain::smt_token_emissions_index, chain::by_symbol_time >( + iterate_results( + _db.get_index< chain::smt_token_emissions_index, chain::by_symbol_time >(), start, result.token_emissions, args.limit, - &database_api_impl::on_push_default< chain::smt_token_emissions_object >, - &database_api_impl::filter_default< chain::smt_token_emissions_object > ); + &on_push_default< chain::smt_token_emissions_object >, + &filter_default< chain::smt_token_emissions_object > ); break; } default: @@ -2096,12 +2108,13 @@ DEFINE_API_IMPL( database_api_impl, list_smt_token_balances ) key[ 0 ].as< account_name_type >(), asset_symbol_type::from_asset_num( key[ 1 ].as< asset_symbol_type >().get_stripped_precision_smt_num() ) ); - iterate_results< chain::account_regular_balance_index, chain::by_name_stripped_symbol >( + iterate_results( + _db.get_index< chain::account_regular_balance_index, chain::by_name_stripped_symbol >(), start, result.balances, args.limit, [&]( const chain::account_regular_balance_object& b ){ return api_smt_account_balance_object( b, _db ); }, - &database_api_impl::filter_default< chain::account_regular_balance_object > ); + &filter_default< chain::account_regular_balance_object > ); break; } default: diff --git a/libraries/plugins/apis/rc_api/CMakeLists.txt b/libraries/plugins/apis/rc_api/CMakeLists.txt index d1a59c8dde..96cc224c98 100644 --- a/libraries/plugins/apis/rc_api/CMakeLists.txt +++ b/libraries/plugins/apis/rc_api/CMakeLists.txt @@ -5,7 +5,7 @@ add_library( rc_api_plugin ${HEADERS} ) -target_link_libraries( rc_api_plugin rc_plugin json_rpc_plugin ) +target_link_libraries( rc_api_plugin rc_plugin database_api_plugin json_rpc_plugin ) target_include_directories( rc_api_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) if( CLANG_TIDY_EXE ) diff --git a/libraries/plugins/apis/rc_api/include/steem/plugins/rc_api/rc_api.hpp b/libraries/plugins/apis/rc_api/include/steem/plugins/rc_api/rc_api.hpp index 99b88551d9..d4950a4943 100644 --- a/libraries/plugins/apis/rc_api/include/steem/plugins/rc_api/rc_api.hpp +++ b/libraries/plugins/apis/rc_api/include/steem/plugins/rc_api/rc_api.hpp @@ -17,6 +17,20 @@ namespace detail class rc_api_impl; } +enum sort_order_type +{ + by_name, + by_edge, + by_pool +}; + +struct list_object_args_type +{ + fc::variant start; + uint32_t limit; + sort_order_type order; +}; + using plugins::json_rpc::void_type; typedef void_type get_resource_params_args; @@ -40,12 +54,53 @@ struct get_resource_pool_return variant_object resource_pool; }; +struct pool_delegation +{ + steem::chain::util::manabar rc_manabar; + int64_t max_mana = 0; +}; + struct rc_account_api_object { - account_name_type account; + rc_account_api_object( const rc_account_object& rca, const database& db ) : + account( rca.account ), + creator( rca.creator ), + rc_manabar( rca.rc_manabar ), + max_rc_creation_adjustment( rca.max_rc_creation_adjustment ), + vests_delegated_to_pools( rca.vests_delegated_to_pools ), + delegation_slots( rca.indel_slots ), + out_delegation_total( rca.out_delegations ) + { + max_rc = get_maximum_rc( db.get_account( account ), rca ); + + for( const auto& pool : delegation_slots ) + { + pool_delegation del; + + auto indel_edge = db.find< rc_outdel_drc_edge_object, by_edge >( boost::make_tuple( pool, account, VESTS_SYMBOL ) ); + if( indel_edge != nullptr ) + { + del.rc_manabar = indel_edge->drc_manabar; + del.max_mana = indel_edge->drc_max_mana; + } + + incoming_delegations[ pool ] = del; + } + } + + account_name_type account; + account_name_type creator; steem::chain::util::manabar rc_manabar; - asset max_rc_creation_adjustment = asset( 0, VESTS_SYMBOL ); - int64_t max_rc = 0; + asset max_rc_creation_adjustment = asset( 0, VESTS_SYMBOL ); + int64_t max_rc = 0; + asset vests_delegated_to_pools = asset( 0 , VESTS_SYMBOL ); + fc::array< account_name_type, STEEM_RC_MAX_SLOTS > + delegation_slots; + + flat_map< account_name_type, pool_delegation > + incoming_delegations; + + uint32_t out_delegation_total = 0; // // This is used for bug-catching, to match that the vesting shares in a @@ -61,14 +116,50 @@ struct rc_account_api_object struct find_rc_accounts_args { - std::vector< account_name_type > accounts; + std::vector< account_name_type > accounts; }; struct find_rc_accounts_return { - std::vector< rc_account_api_object > rc_accounts; + std::vector< rc_account_api_object > rc_accounts; +}; + +typedef list_object_args_type list_rc_accounts_args; + +typedef find_rc_accounts_return list_rc_accounts_return; + +typedef rc_delegation_pool_object rc_delegation_pool_api_object; + +struct find_rc_delegation_pools_args +{ + std::vector< account_name_type > accounts; +}; + +struct find_rc_delegation_pools_return +{ + std::vector< rc_delegation_pool_api_object > rc_delegation_pools; }; +typedef list_object_args_type list_rc_delegation_pools_args; + +typedef find_rc_delegation_pools_return list_rc_delegation_pools_return; + +typedef rc_indel_edge_object rc_indel_edge_api_object; + +struct find_rc_delegations_args +{ + account_name_type account; +}; + +struct find_rc_delegations_return +{ + std::vector< rc_indel_edge_api_object > rc_delegations; +}; + +typedef list_object_args_type list_rc_delegations_args; + +typedef find_rc_delegations_return list_rc_delegations_return; + class rc_api { public: @@ -79,6 +170,11 @@ class rc_api (get_resource_params) (get_resource_pool) (find_rc_accounts) + (list_rc_accounts) + (find_rc_delegation_pools) + (list_rc_delegation_pools) + (find_rc_delegations) + (list_rc_delegations) ) private: @@ -87,31 +183,55 @@ class rc_api } } } // steem::plugins::rc +FC_REFLECT_ENUM( steem::plugins::rc::sort_order_type, + (by_name) + (by_edge) + (by_pool) ) + +FC_REFLECT( steem::plugins::rc::list_object_args_type, + (start) + (limit) + (order) ) + FC_REFLECT( steem::plugins::rc::get_resource_params_return, (resource_names) (resource_params) - (size_info) - ) + (size_info) ) FC_REFLECT( steem::plugins::rc::resource_pool_api_object, - (pool) - ) + (pool) ) FC_REFLECT( steem::plugins::rc::get_resource_pool_return, - (resource_pool) - ) + (resource_pool) ) + +FC_REFLECT( steem::plugins::rc::pool_delegation, + (rc_manabar) + (max_mana) ) FC_REFLECT( steem::plugins::rc::rc_account_api_object, (account) + (creator) (rc_manabar) (max_rc_creation_adjustment) (max_rc) - ) + (delegation_slots) + (incoming_delegations) + (out_delegation_total) ) FC_REFLECT( steem::plugins::rc::find_rc_accounts_args, - (accounts) - ) + (accounts) ) FC_REFLECT( steem::plugins::rc::find_rc_accounts_return, - (rc_accounts) - ) + (rc_accounts) ) + +FC_REFLECT( steem::plugins::rc::find_rc_delegation_pools_args, + (accounts) ) + +FC_REFLECT( steem::plugins::rc::find_rc_delegation_pools_return, + (rc_delegation_pools) ) + +FC_REFLECT( steem::plugins::rc::find_rc_delegations_args, + (account) ) + +FC_REFLECT( steem::plugins::rc::find_rc_delegations_return, + (rc_delegations) ) diff --git a/libraries/plugins/apis/rc_api/rc_api.cpp b/libraries/plugins/apis/rc_api/rc_api.cpp index 4d11351f06..be8de2a97e 100644 --- a/libraries/plugins/apis/rc_api/rc_api.cpp +++ b/libraries/plugins/apis/rc_api/rc_api.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include #include @@ -13,6 +15,8 @@ namespace steem { namespace plugins { namespace rc { namespace detail { +using namespace database_api::util; + class rc_api_impl { public: @@ -23,6 +27,11 @@ class rc_api_impl (get_resource_params) (get_resource_pool) (find_rc_accounts) + (list_rc_accounts) + (find_rc_delegation_pools) + (list_rc_delegation_pools) + (find_rc_delegations) + (list_rc_delegations) ) chain::database& _db; @@ -80,31 +89,153 @@ DEFINE_API_IMPL( rc_api_impl, get_resource_pool ) DEFINE_API_IMPL( rc_api_impl, find_rc_accounts ) { - find_rc_accounts_return result; - FC_ASSERT( args.accounts.size() <= RC_API_SINGLE_QUERY_LIMIT ); + find_rc_accounts_return result; + result.rc_accounts.reserve( args.accounts.size() ); + for( const account_name_type& a : args.accounts ) { const rc_account_object* rc_account = _db.find< rc_account_object, by_name >( a ); - if( rc_account == nullptr ) - continue; + if( rc_account != nullptr ) + { + result.rc_accounts.emplace_back( *rc_account, _db ); + } + } + + return result; +} + +DEFINE_API_IMPL( rc_api_impl, list_rc_accounts ) +{ + FC_ASSERT( args.limit <= RC_API_SINGLE_QUERY_LIMIT ); + + list_rc_accounts_return result; + result.rc_accounts.reserve( args.limit ); + + switch( args.order ) + { + case( by_name ): + { + iterate_results( + _db.get_index< rc_account_index, by_name >(), + args.start.as< account_name_type >, + result.rc_accounts, + args.limit, + [&]( const rc_account_object& rca ){ return rc_account_api_object( rca, _db ); } + &filter_default< rc_account_object > ); + break; + } + default: + FC_ASSERT( false, "Unknown or unsupported sort order" ); + } +} + +DEFINE_API_IMPL( rc_api_impl, find_rc_delegation_pools ) +{ + FC_ASSERT( args.accounts.size() <= RC_API_SINGLE_QUERY_LIMIT ); - const account_object& account = _db.get< account_object, by_name >( a ); + find_rc_delegation_pools_return result; + result.rc_delegation_pools.reserve( args.accounts.size() ); - rc_account_api_object api_rc_account; - api_rc_account.account = rc_account->account; - api_rc_account.rc_manabar = rc_account->rc_manabar; - api_rc_account.max_rc_creation_adjustment = rc_account->max_rc_creation_adjustment; - api_rc_account.max_rc = get_maximum_rc( account, *rc_account ); + for( const auto& a : args.accounts ) + { + const auto* pool = _db.find< rc_delegation_pool_object, by_account_symbol >( boost::make_tuple( a, VESTS_SYMBOL ) ); - result.rc_accounts.emplace_back( api_rc_account ); + if( pool != nullptr ) + { + result.rc_delegation_pools.push_back( *pool ); + } } return result; } +DEFINE_API_IMPL( rc_api_impl, list_rc_delegation_pools ) +{ + FC_ASSERT( args.limit <= RC_API_SINGLE_QUERY_LIMIT ); + + list_rc_delegation_pools_return result; + result.rc_delegation_pools.reserve( args.limit ); + + switch( args.order ) + { + case( by_name ): + { + iterate_results( + _db.get_index< rc_delegation_pool_index, by_account_symbol >(), + boost::make_tuple( args.start.as< account_name_type >(), VESTS_SYMBOL ), + result.rc_delegation_pools, + args.limit, + &on_push_default< rc_delegation_pool_object > + &filter_default< rc_delegation_pool_object > ); + break; + } + default: + FC_ASSERT( false, "Unknown or unsupported sort order" ); + } +} + +DEFINE_API_IMPL( rc_api_impl, find_rc_delegations ) +{ + static_assert( STEEM_RC_MAX_INDEL <= RC_API_SINGLE_QUERY_LIMIT, "STEEM_RC_MAX_INDEL exceeds RC_API_SINGLE_QUERY_LIMIT" ); + + find_rc_delegations_return result; + result.rc_delegations.reserve( STEEM_RC_MAX_INDEL ); + + const auto& del_idx = _db.get_index< rc_outdel_drc_edge_index, by_edge >(); + + for( auto itr = del_idx.lower_bound( args.account ); itr != del_idx.end() && itr->from_account == args.account; ++itr ) + { + result.rc_delegations.push_back( *itr ); + } + + return result; +} + +DEFINE_API_IMPL( rc_api_impl, list_rc_delegations ) +{ + FC_ASSERT( args.limit <= RC_API_SINGLE_QUERY_LIMIT ); + + list_rc_delegations_return result; + result.rc_delegations.reserve( args.limit ); + + switch( args.order ) + { + case( by_edge ): + { + auto key = args.start.as< vector< fc::variant > >(); + FC_ASSERT( key.size() == 2, "by_edge start requires 2 values. (from_account, pool_name)" ); + + iterate_results( + _db.get_index< rc_outdel_drc_edge_index, by_edge >(), + boost::make_tuple( key[0].as< account_name_type >(), key[1].as< account_name_type >() ), + result.rc_delegations, + args.limit, + &on_push_default< rc_outdel_drc_edge_object > + &filter_default< rc_outdel_drc_edge_object > ); + break; + } + case( by_pool ): + { + auto key = args.start.as< vector< fc::variant > >(); + FC_ASSERT( key.size() == 2, "by_edge start requires 2 values. (from_account, pool_name)" ); + + iterate_results( + _db.get_index< rc_outdel_drc_edge_index, by_pool >(), + boost::make_tuple( key[0].as< account_name_type >(), key[1].as< account_name_type >() ), + result.rc_delegations, + args.limit, + &on_push_default< rc_outdel_drc_edge_object > + &filter_default< rc_outdel_drc_edge_object > ); + break; + } + default: + FC_ASSERT( false, "Unknown or unsupported sort order" ); + } +} + } // detail rc_api::rc_api(): my( new detail::rc_api_impl() ) @@ -118,6 +249,11 @@ DEFINE_READ_APIS( rc_api, (get_resource_params) (get_resource_pool) (find_rc_accounts) + (list_rc_accounts) + (find_rc_delegation_pools) + (list_rc_delegation_pools) + (find_rc_delegations) + (list_rc_delegations) ) } } } // steem::plugins::rc diff --git a/libraries/plugins/rc/include/steem/plugins/rc/rc_objects.hpp b/libraries/plugins/rc/include/steem/plugins/rc/rc_objects.hpp index 3b3d18fa28..596aad2df4 100644 --- a/libraries/plugins/rc/include/steem/plugins/rc/rc_objects.hpp +++ b/libraries/plugins/rc/include/steem/plugins/rc/rc_objects.hpp @@ -287,6 +287,13 @@ typedef multi_index_container< const_mem_fun< rc_indel_edge_object, asset_symbol_type, &rc_indel_edge_object::get_asset_symbol >, member< rc_indel_edge_object, account_name_type, &rc_indel_edge_object::to_pool > > + >, + ordered_unique< tag< by_pool >, + composite_key< rc_indel_edge_object, + member< rc_indel_edge_object, account_name_type, &rc_indel_edge_object::to_pool >, + const_mem_fun< rc_indel_edge_object, asset_symbol_type, &rc_indel_edge_object::get_asset_symbol >, + member< rc_indel_edge_object, account_name_type, &rc_indel_edge_object::from_account > + > > >, allocator< rc_indel_edge_object >