#235 - fix bookie plugin. Don't use db for secondary_index

This commit is contained in:
Vlad Dobromyslov 2022-02-21 09:10:58 +03:00
parent cca322573b
commit ac1be63ddd
4 changed files with 246 additions and 307 deletions

View file

@ -29,7 +29,6 @@
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/affiliate_stats/affiliate_stats_objects.hpp>

View file

@ -157,37 +157,45 @@ fc::variants bookie_api_impl::get_objects(const vector<object_id_type>& ids) con
{
case event_id_type::type_id:
{
auto& persistent_events_by_event_id = db->get_index_type<detail::persistent_event_index>().indices().get<by_event_id>();
auto iter = persistent_events_by_event_id.find(id.as<event_id_type>());
if (iter != persistent_events_by_event_id.end())
return iter->ephemeral_event_object.to_variant();
const auto &idx = db->get_index_type<event_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_event_index>();
auto iter = refs.ephemeral_event_object.find(id.as<event_id_type>());
if (iter != refs.ephemeral_event_object.end())
return iter->second.to_variant();
else
return {};
}
case bet_id_type::type_id:
{
auto& persistent_bets_by_bet_id = db->get_index_type<detail::persistent_bet_index>().indices().get<by_bet_id>();
auto iter = persistent_bets_by_bet_id.find(id.as<bet_id_type>());
if (iter != persistent_bets_by_bet_id.end())
return iter->ephemeral_bet_object.to_variant();
const auto &idx = db->get_index_type<bet_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_bet_index>();
auto iter = refs.internal.find(id.as<bet_id_type>());
if (iter != refs.internal.end())
return iter->second.ephemeral_bet_object.to_variant();
else
return {};
}
case betting_market_object::type_id:
{
auto& persistent_betting_markets_by_betting_market_id = db->get_index_type<detail::persistent_betting_market_index>().indices().get<by_betting_market_id>();
auto iter = persistent_betting_markets_by_betting_market_id.find(id.as<betting_market_id_type>());
if (iter != persistent_betting_markets_by_betting_market_id.end())
return iter->ephemeral_betting_market_object.to_variant();
{
const auto &idx = db->get_index_type<betting_market_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_betting_market_index>();
auto iter = refs.ephemeral_betting_market_object.find(id.as<betting_market_id_type>());
if (iter != refs.ephemeral_betting_market_object.end())
return iter->second.to_variant();
else
return {};
}
case betting_market_group_object::type_id:
{
auto& persistent_betting_market_groups_by_betting_market_group_id = db->get_index_type<detail::persistent_betting_market_group_index>().indices().get<by_betting_market_group_id>();
auto iter = persistent_betting_market_groups_by_betting_market_group_id.find(id.as<betting_market_group_id_type>());
if (iter != persistent_betting_market_groups_by_betting_market_group_id.end())
return iter->ephemeral_betting_market_group_object.to_variant();
{
const auto &idx = db->get_index_type<betting_market_group_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_betting_market_group_index>();
auto iter = refs.internal.find(id.as<betting_market_group_id_type>());
if (iter != refs.internal.end())
return iter->second.ephemeral_betting_market_group_object.to_variant();
else
return {};
}
@ -203,25 +211,28 @@ std::vector<matched_bet_object> bookie_api_impl::get_matched_bets_for_bettor(acc
{
std::vector<matched_bet_object> result;
std::shared_ptr<graphene::chain::database> db = app.chain_database();
auto& persistent_bets_by_bettor_id = db->get_index_type<detail::persistent_bet_index>().indices().get<by_bettor_id>();
auto iter = persistent_bets_by_bettor_id.lower_bound(std::make_tuple(bettor_id, true));
while (iter != persistent_bets_by_bettor_id.end() &&
iter->get_bettor_id() == bettor_id &&
iter->is_matched())
{
matched_bet_object match;
match.id = iter->ephemeral_bet_object.id;
match.bettor_id = iter->ephemeral_bet_object.bettor_id;
match.betting_market_id = iter->ephemeral_bet_object.betting_market_id;
match.amount_to_bet = iter->ephemeral_bet_object.amount_to_bet;
match.back_or_lay = iter->ephemeral_bet_object.back_or_lay;
match.end_of_delay = iter->ephemeral_bet_object.end_of_delay;
match.amount_matched = iter->amount_matched;
match.associated_operations = iter->associated_operations;
result.emplace_back(std::move(match));
const auto &idx = db->get_index_type<bet_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_bet_index>();
++iter;
for( const auto& bet_pair : refs.internal )
{
const auto& bet = bet_pair.second;
if( bet.get_bettor_id() == bettor_id && bet.is_matched() )
{
matched_bet_object match;
match.id = bet.ephemeral_bet_object.id;
match.bettor_id = bet.ephemeral_bet_object.bettor_id;
match.betting_market_id = bet.ephemeral_bet_object.betting_market_id;
match.amount_to_bet = bet.ephemeral_bet_object.amount_to_bet;
match.back_or_lay = bet.ephemeral_bet_object.back_or_lay;
match.end_of_delay = bet.ephemeral_bet_object.end_of_delay;
match.amount_matched = bet.amount_matched;
match.associated_operations = bet.associated_operations;
result.emplace_back(std::move(match));
}
}
return result;
}
@ -231,29 +242,32 @@ std::vector<matched_bet_object> bookie_api_impl::get_all_matched_bets_for_bettor
std::vector<matched_bet_object> result;
std::shared_ptr<graphene::chain::database> db = app.chain_database();
auto& persistent_bets_by_bettor_id = db->get_index_type<detail::persistent_bet_index>().indices().get<by_bettor_id>();
persistent_bet_multi_index_type::index<by_bettor_id>::type::iterator iter;
if (start == bet_id_type())
iter = persistent_bets_by_bettor_id.lower_bound(std::make_tuple(bettor_id, true));
else
iter = persistent_bets_by_bettor_id.lower_bound(std::make_tuple(bettor_id, true, start));
while (iter != persistent_bets_by_bettor_id.end() &&
iter->get_bettor_id() == bettor_id &&
iter->is_matched() &&
result.size() < limit)
{
matched_bet_object match;
match.id = iter->ephemeral_bet_object.id;
match.bettor_id = iter->ephemeral_bet_object.bettor_id;
match.betting_market_id = iter->ephemeral_bet_object.betting_market_id;
match.amount_to_bet = iter->ephemeral_bet_object.amount_to_bet;
match.back_or_lay = iter->ephemeral_bet_object.back_or_lay;
match.end_of_delay = iter->ephemeral_bet_object.end_of_delay;
match.amount_matched = iter->amount_matched;
result.emplace_back(std::move(match));
const auto &idx = db->get_index_type<bet_object_index>();
const auto &aidx = dynamic_cast<const base_primary_index &>(idx);
const auto &refs = aidx.get_secondary_index<detail::persistent_bet_index>();
++iter;
for( const auto& bet_pair : refs.internal )
{
const auto& bet_id = bet_pair.first;
const auto& bet = bet_pair.second;
if( bet.get_bettor_id() == bettor_id &&
bet.is_matched() &&
bet_id > start &&
result.size() < limit )
{
matched_bet_object match;
match.id = bet.ephemeral_bet_object.id;
match.bettor_id = bet.ephemeral_bet_object.bettor_id;
match.betting_market_id = bet.ephemeral_bet_object.betting_market_id;
match.amount_to_bet = bet.ephemeral_bet_object.amount_to_bet;
match.back_or_lay = bet.ephemeral_bet_object.back_or_lay;
match.end_of_delay = bet.ephemeral_bet_object.end_of_delay;
match.amount_matched = bet.amount_matched;
match.associated_operations = bet.associated_operations;
result.emplace_back(std::move(match));
}
}
return result;
}

View file

@ -59,143 +59,67 @@ namespace detail
* We do this by creating a secondary index on bet_object. We don't actually use it
* to index any property of the bet, we just use it to register for callbacks.
*/
class persistent_bet_object_helper : public secondary_index
{
public:
virtual ~persistent_bet_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_bet_object_helper::object_inserted(const object& obj)
void persistent_bet_index::object_inserted(const object& obj)
{
const bet_object& bet_obj = *boost::polymorphic_downcast<const bet_object*>(&obj);
_bookie_plugin->database().create<persistent_bet_object>([&](persistent_bet_object& saved_bet_obj) {
saved_bet_obj.ephemeral_bet_object = bet_obj;
});
internal.insert( {bet_obj.id, bet_obj} );
}
void persistent_bet_object_helper::object_modified(const object& after)
void persistent_bet_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
const bet_object& bet_obj = *boost::polymorphic_downcast<const bet_object*>(&after);
auto iter = persistent_bets_by_bet_id.find(bet_obj.id);
assert (iter != persistent_bets_by_bet_id.end());
if (iter != persistent_bets_by_bet_id.end())
db.modify(*iter, [&](persistent_bet_object& saved_bet_obj) {
saved_bet_obj.ephemeral_bet_object = bet_obj;
});
auto iter = internal.find(bet_obj.id);
assert (iter != internal.end());
if (iter != internal.end())
iter->second = bet_obj;
}
//////////// end bet_object ///////////////////
class persistent_betting_market_object_helper : public secondary_index
{
public:
virtual ~persistent_betting_market_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_betting_market_object_helper::object_inserted(const object& obj)
void persistent_betting_market_index::object_inserted(const object& obj)
{
const betting_market_object& betting_market_obj = *boost::polymorphic_downcast<const betting_market_object*>(&obj);
_bookie_plugin->database().create<persistent_betting_market_object>([&](persistent_betting_market_object& saved_betting_market_obj) {
saved_betting_market_obj.ephemeral_betting_market_object = betting_market_obj;
});
ephemeral_betting_market_object.insert( {betting_market_obj.id, betting_market_obj} );
}
void persistent_betting_market_object_helper::object_modified(const object& after)
void persistent_betting_market_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_betting_markets_by_betting_market_id = db.get_index_type<persistent_betting_market_index>().indices().get<by_betting_market_id>();
const betting_market_object& betting_market_obj = *boost::polymorphic_downcast<const betting_market_object*>(&after);
auto iter = persistent_betting_markets_by_betting_market_id.find(betting_market_obj.id);
assert (iter != persistent_betting_markets_by_betting_market_id.end());
if (iter != persistent_betting_markets_by_betting_market_id.end())
db.modify(*iter, [&](persistent_betting_market_object& saved_betting_market_obj) {
saved_betting_market_obj.ephemeral_betting_market_object = betting_market_obj;
});
auto iter = ephemeral_betting_market_object.find(betting_market_obj.id);
assert (iter != ephemeral_betting_market_object.end());
if (iter != ephemeral_betting_market_object.end())
iter->second = betting_market_obj;
}
//////////// end betting_market_object ///////////////////
class persistent_betting_market_group_object_helper : public secondary_index
{
public:
virtual ~persistent_betting_market_group_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_betting_market_group_object_helper::object_inserted(const object& obj)
void persistent_betting_market_group_index::object_inserted(const object& obj)
{
const betting_market_group_object& betting_market_group_obj = *boost::polymorphic_downcast<const betting_market_group_object*>(&obj);
_bookie_plugin->database().create<persistent_betting_market_group_object>([&](persistent_betting_market_group_object& saved_betting_market_group_obj) {
saved_betting_market_group_obj.ephemeral_betting_market_group_object = betting_market_group_obj;
});
internal.insert( {betting_market_group_obj.id, betting_market_group_obj} );
}
void persistent_betting_market_group_object_helper::object_modified(const object& after)
void persistent_betting_market_group_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_betting_market_groups_by_betting_market_group_id = db.get_index_type<persistent_betting_market_group_index>().indices().get<by_betting_market_group_id>();
const betting_market_group_object& betting_market_group_obj = *boost::polymorphic_downcast<const betting_market_group_object*>(&after);
auto iter = persistent_betting_market_groups_by_betting_market_group_id.find(betting_market_group_obj.id);
assert (iter != persistent_betting_market_groups_by_betting_market_group_id.end());
if (iter != persistent_betting_market_groups_by_betting_market_group_id.end())
db.modify(*iter, [&](persistent_betting_market_group_object& saved_betting_market_group_obj) {
saved_betting_market_group_obj.ephemeral_betting_market_group_object = betting_market_group_obj;
});
auto iter = internal.find(betting_market_group_obj.id);
assert (iter != internal.end());
if (iter != internal.end())
iter->second = betting_market_group_obj;
}
//////////// end betting_market_group_object ///////////////////
class persistent_event_object_helper : public secondary_index
{
public:
virtual ~persistent_event_object_helper() {}
virtual void object_inserted(const object& obj) override;
//virtual void object_removed( const object& obj ) override;
//virtual void about_to_modify( const object& before ) override;
virtual void object_modified(const object& after) override;
void set_plugin_instance(bookie_plugin* instance) { _bookie_plugin = instance; }
private:
bookie_plugin* _bookie_plugin;
};
void persistent_event_object_helper::object_inserted(const object& obj)
void persistent_event_index::object_inserted(const object& obj)
{
const event_object& event_obj = *boost::polymorphic_downcast<const event_object*>(&obj);
_bookie_plugin->database().create<persistent_event_object>([&](persistent_event_object& saved_event_obj) {
saved_event_obj.ephemeral_event_object = event_obj;
});
ephemeral_event_object.insert( {event_obj.id, event_obj} );
}
void persistent_event_object_helper::object_modified(const object& after)
void persistent_event_index::object_modified(const object& after)
{
database& db = _bookie_plugin->database();
auto& persistent_events_by_event_id = db.get_index_type<persistent_event_index>().indices().get<by_event_id>();
const event_object& event_obj = *boost::polymorphic_downcast<const event_object*>(&after);
auto iter = persistent_events_by_event_id.find(event_obj.id);
assert (iter != persistent_events_by_event_id.end());
if (iter != persistent_events_by_event_id.end())
db.modify(*iter, [&](persistent_event_object& saved_event_obj) {
saved_event_obj.ephemeral_event_object = event_obj;
});
auto iter = ephemeral_event_object.find(event_obj.id);
assert (iter != ephemeral_event_object.end());
if (iter != ephemeral_event_object.end())
iter->second = event_obj;
}
//////////// end event_object ///////////////////
@ -207,7 +131,6 @@ class bookie_plugin_impl
{ }
virtual ~bookie_plugin_impl();
/**
* Called After a block has been applied and committed. The callback
* should not yield and should execute quickly.
@ -299,27 +222,35 @@ void bookie_plugin_impl::on_block_applied( const signed_block& )
const asset& amount_bet = bet_matched_op.amount_bet;
// object may no longer exist
//const bet_object& bet = bet_matched_op.bet_id(db);
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
auto bet_iter = persistent_bets_by_bet_id.find(bet_matched_op.bet_id);
assert(bet_iter != persistent_bets_by_bet_id.end());
if (bet_iter != persistent_bets_by_bet_id.end())
const auto &idx_bet_object = db.get_index_type<bet_object_index>();
const auto &aidx_bet_object = dynamic_cast<const base_primary_index &>(idx_bet_object);
const auto &refs_bet_object = aidx_bet_object.get_secondary_index<detail::persistent_bet_index>();
auto& nonconst_refs_bet_object = const_cast<persistent_bet_index&>(refs_bet_object);
auto bet_iter = nonconst_refs_bet_object.internal.find(bet_matched_op.bet_id);
assert(bet_iter != nonconst_refs_bet_object.internal.end());
if (bet_iter != nonconst_refs_bet_object.internal.end())
{
db.modify(*bet_iter, [&]( persistent_bet_object& obj ) {
obj.amount_matched += amount_bet.amount;
if (is_operation_history_object_stored(op.id))
obj.associated_operations.emplace_back(op.id);
});
const bet_object& bet_obj = bet_iter->ephemeral_bet_object;
bet_iter->second.amount_matched += amount_bet.amount;
if (is_operation_history_object_stored(op.id))
bet_iter->second.associated_operations.emplace_back(op.id);
auto& persistent_betting_market_idx = db.get_index_type<persistent_betting_market_index>().indices().get<by_betting_market_id>();
auto persistent_betting_market_object_iter = persistent_betting_market_idx.find(bet_obj.betting_market_id);
FC_ASSERT(persistent_betting_market_object_iter != persistent_betting_market_idx.end());
const betting_market_object& betting_market = persistent_betting_market_object_iter->ephemeral_betting_market_object;
const bet_object& bet_obj = bet_iter->second.ephemeral_bet_object;
auto& persistent_betting_market_group_idx = db.get_index_type<persistent_betting_market_group_index>().indices().get<by_betting_market_group_id>();
auto persistent_betting_market_group_object_iter = persistent_betting_market_group_idx.find(betting_market.group_id);
FC_ASSERT(persistent_betting_market_group_object_iter != persistent_betting_market_group_idx.end());
const betting_market_group_object& betting_market_group = persistent_betting_market_group_object_iter->ephemeral_betting_market_group_object;
const auto &idx_betting_market = db.get_index_type<betting_market_object_index>();
const auto &aidx_betting_market = dynamic_cast<const base_primary_index &>(idx_betting_market);
const auto &refs_betting_market = aidx_betting_market.get_secondary_index<detail::persistent_betting_market_index>();
auto persistent_betting_market_object_iter = refs_betting_market.ephemeral_betting_market_object.find(bet_obj.betting_market_id);
FC_ASSERT(persistent_betting_market_object_iter != refs_betting_market.ephemeral_betting_market_object.end());
const betting_market_object& betting_market = persistent_betting_market_object_iter->second;
const auto &idx_betting_market_group = db.get_index_type<betting_market_group_object_index>();
const auto &aidx_betting_market_group = dynamic_cast<const base_primary_index &>(idx_betting_market_group);
const auto &refs_betting_market_group = aidx_betting_market_group.get_secondary_index<detail::persistent_betting_market_group_index>();
auto& nonconst_refs_betting_market_group = const_cast<persistent_betting_market_group_index&>(refs_betting_market_group);
auto persistent_betting_market_group_object_iter = nonconst_refs_betting_market_group.internal.find(betting_market.group_id);
FC_ASSERT(persistent_betting_market_group_object_iter != nonconst_refs_betting_market_group.internal.end());
const betting_market_group_object& betting_market_group = persistent_betting_market_group_object_iter->second.ephemeral_betting_market_group_object;
// if the object is still in the main database, keep the running total there
// otherwise, add it directly to the persistent version
@ -330,9 +261,7 @@ void bookie_plugin_impl::on_block_applied( const signed_block& )
obj.total_matched_bets_amount += amount_bet.amount;
});
else
db.modify( *persistent_betting_market_group_object_iter, [&]( persistent_betting_market_group_object& obj ){
obj.ephemeral_betting_market_group_object.total_matched_bets_amount += amount_bet.amount;
});
persistent_betting_market_group_object_iter->second.total_matched_bets_amount += amount_bet.amount;
}
}
else if( op.op.which() == operation::tag<event_create_operation>::value )
@ -364,33 +293,35 @@ void bookie_plugin_impl::on_block_applied( const signed_block& )
else if ( op.op.which() == operation::tag<bet_canceled_operation>::value )
{
const bet_canceled_operation& bet_canceled_op = op.op.get<bet_canceled_operation>();
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
auto bet_iter = persistent_bets_by_bet_id.find(bet_canceled_op.bet_id);
assert(bet_iter != persistent_bets_by_bet_id.end());
if (bet_iter != persistent_bets_by_bet_id.end())
const auto &idx_bet_object = db.get_index_type<bet_object_index>();
const auto &aidx_bet_object = dynamic_cast<const base_primary_index &>(idx_bet_object);
const auto &refs_bet_object = aidx_bet_object.get_secondary_index<detail::persistent_bet_index>();
auto& nonconst_refs_bet_object = const_cast<persistent_bet_index&>(refs_bet_object);
auto bet_iter = nonconst_refs_bet_object.internal.find(bet_canceled_op.bet_id);
assert(bet_iter != nonconst_refs_bet_object.internal.end());
if (bet_iter != nonconst_refs_bet_object.internal.end())
{
// ilog("Adding bet_canceled_operation ${canceled_id} to bet ${bet_id}'s associated operations",
// ("canceled_id", op.id)("bet_id", bet_canceled_op.bet_id));
if (is_operation_history_object_stored(op.id))
db.modify(*bet_iter, [&]( persistent_bet_object& obj ) {
obj.associated_operations.emplace_back(op.id);
});
bet_iter->second.associated_operations.emplace_back(op.id);
}
}
else if ( op.op.which() == operation::tag<bet_adjusted_operation>::value )
{
const bet_adjusted_operation& bet_adjusted_op = op.op.get<bet_adjusted_operation>();
auto& persistent_bets_by_bet_id = db.get_index_type<persistent_bet_index>().indices().get<by_bet_id>();
auto bet_iter = persistent_bets_by_bet_id.find(bet_adjusted_op.bet_id);
assert(bet_iter != persistent_bets_by_bet_id.end());
if (bet_iter != persistent_bets_by_bet_id.end())
const auto &idx_bet_object = db.get_index_type<bet_object_index>();
const auto &aidx_bet_object = dynamic_cast<const base_primary_index &>(idx_bet_object);
const auto &refs_bet_object = aidx_bet_object.get_secondary_index<detail::persistent_bet_index>();
auto& nonconst_refs_bet_object = const_cast<persistent_bet_index&>(refs_bet_object);
auto bet_iter = nonconst_refs_bet_object.internal.find(bet_adjusted_op.bet_id);
assert(bet_iter != nonconst_refs_bet_object.internal.end());
if (bet_iter != nonconst_refs_bet_object.internal.end())
{
// ilog("Adding bet_adjusted_operation ${adjusted_id} to bet ${bet_id}'s associated operations",
// ("adjusted_id", op.id)("bet_id", bet_adjusted_op.bet_id));
if (is_operation_history_object_stored(op.id))
db.modify(*bet_iter, [&]( persistent_bet_object& obj ) {
obj.associated_operations.emplace_back(op.id);
});
bet_iter->second.associated_operations.emplace_back(op.id);
}
}
@ -472,31 +403,21 @@ void bookie_plugin::plugin_initialize(const boost::program_options::variables_ma
database().new_objects.connect([this](const vector<object_id_type>& ids, const flat_set<account_id_type>& impacted_accounts) { my->on_objects_new(ids); });
database().removed_objects.connect([this](const vector<object_id_type>& ids, const vector<const object*>& objs, const flat_set<account_id_type>& impacted_accounts) { my->on_objects_removed(ids); });
//auto event_index =
database().add_index<primary_index<detail::persistent_event_index> >();
database().add_index<primary_index<detail::persistent_betting_market_group_index> >();
database().add_index<primary_index<detail::persistent_betting_market_index> >();
database().add_index<primary_index<detail::persistent_bet_index> >();
const primary_index<bet_object_index>& bet_object_idx = database().get_index_type<primary_index<bet_object_index> >();
primary_index<bet_object_index>& nonconst_bet_object_idx = const_cast<primary_index<bet_object_index>&>(bet_object_idx);
detail::persistent_bet_object_helper* persistent_bet_object_helper_index = nonconst_bet_object_idx.add_secondary_index<detail::persistent_bet_object_helper>();
persistent_bet_object_helper_index->set_plugin_instance(this);
nonconst_bet_object_idx.add_secondary_index<detail::persistent_bet_index>();
const primary_index<betting_market_object_index>& betting_market_object_idx = database().get_index_type<primary_index<betting_market_object_index> >();
primary_index<betting_market_object_index>& nonconst_betting_market_object_idx = const_cast<primary_index<betting_market_object_index>&>(betting_market_object_idx);
detail::persistent_betting_market_object_helper* persistent_betting_market_object_helper_index = nonconst_betting_market_object_idx.add_secondary_index<detail::persistent_betting_market_object_helper>();
persistent_betting_market_object_helper_index->set_plugin_instance(this);
nonconst_betting_market_object_idx.add_secondary_index<detail::persistent_betting_market_index>();
const primary_index<betting_market_group_object_index>& betting_market_group_object_idx = database().get_index_type<primary_index<betting_market_group_object_index> >();
primary_index<betting_market_group_object_index>& nonconst_betting_market_group_object_idx = const_cast<primary_index<betting_market_group_object_index>&>(betting_market_group_object_idx);
detail::persistent_betting_market_group_object_helper* persistent_betting_market_group_object_helper_index = nonconst_betting_market_group_object_idx.add_secondary_index<detail::persistent_betting_market_group_object_helper>();
persistent_betting_market_group_object_helper_index->set_plugin_instance(this);
nonconst_betting_market_group_object_idx.add_secondary_index<detail::persistent_betting_market_group_index>();
const primary_index<event_object_index>& event_object_idx = database().get_index_type<primary_index<event_object_index> >();
primary_index<event_object_index>& nonconst_event_object_idx = const_cast<primary_index<event_object_index>&>(event_object_idx);
detail::persistent_event_object_helper* persistent_event_object_helper_index = nonconst_event_object_idx.add_secondary_index<detail::persistent_event_object_helper>();
persistent_event_object_helper_index->set_plugin_instance(this);
nonconst_event_object_idx.add_secondary_index<detail::persistent_event_index>();
ilog("bookie plugin: plugin_startup() end");
}

View file

@ -29,39 +29,21 @@
namespace graphene { namespace bookie {
using namespace chain;
enum bookie_object_type
{
persistent_event_object_type,
persistent_betting_market_group_object_type,
persistent_betting_market_object_type,
persistent_bet_object_type,
BOOKIE_OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
};
namespace detail
{
class persistent_event_object : public graphene::db::abstract_object<persistent_event_object>
/**
* @brief This secondary index will allow a reverse lookup of all events that happened
*/
class persistent_event_index : public secondary_index
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_event_object_type;
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
event_object ephemeral_event_object;
event_id_type get_event_id() const { return ephemeral_event_object.id; }
map< event_id_type, event_object > ephemeral_event_object;
};
typedef object_id<bookie_objects, persistent_event_object_type, persistent_event_object> persistent_event_id_type;
struct by_event_id;
typedef multi_index_container<
persistent_event_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_event_id>, const_mem_fun<persistent_event_object, event_id_type, &persistent_event_object::get_event_id> > > > persistent_event_multi_index_type;
typedef generic_index<persistent_event_object, persistent_event_multi_index_type> persistent_event_index;
#if 0 // we no longer have competitors, just leaving this here as an example of how to do a secondary index
class events_by_competitor_index : public secondary_index
{
@ -101,95 +83,118 @@ void events_by_competitor_index::object_modified( const object& after )
}
#endif
//////////// betting_market_group_object //////////////////
class persistent_betting_market_group_object : public graphene::db::abstract_object<persistent_betting_market_group_object>
/**
* @brief This secondary index will allow a reverse lookup of all betting_market_group that happened
*/
class persistent_betting_market_group_index : public secondary_index
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_betting_market_group_object_type;
public:
struct internal_type
{
internal_type(const betting_market_group_object& other)
: ephemeral_betting_market_group_object{other}
{}
internal_type& operator=(const betting_market_group_object& other)
{
ephemeral_betting_market_group_object = other;
return *this;
}
friend bool operator==(const internal_type& lhs, const internal_type& rhs);
friend bool operator<(const internal_type& lhs, const internal_type& rhs);
friend bool operator>(const internal_type& lhs, const internal_type& rhs);
betting_market_group_object ephemeral_betting_market_group_object;
share_type total_matched_bets_amount;
};
betting_market_group_id_type get_betting_market_group_id() const { return ephemeral_betting_market_group_object.id; }
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
map< betting_market_group_id_type, internal_type > internal;
};
struct by_betting_market_group_id;
typedef multi_index_container<
persistent_betting_market_group_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_betting_market_group_id>, const_mem_fun<persistent_betting_market_group_object, betting_market_group_id_type, &persistent_betting_market_group_object::get_betting_market_group_id> > > > persistent_betting_market_group_multi_index_type;
typedef generic_index<persistent_betting_market_group_object, persistent_betting_market_group_multi_index_type> persistent_betting_market_group_index;
//////////// betting_market_object //////////////////
class persistent_betting_market_object : public graphene::db::abstract_object<persistent_betting_market_object>
inline bool operator==(const persistent_betting_market_group_index::internal_type& lhs, const persistent_betting_market_group_index::internal_type& rhs)
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_betting_market_object_type;
return lhs.ephemeral_betting_market_group_object == rhs.ephemeral_betting_market_group_object;
}
betting_market_object ephemeral_betting_market_object;
inline bool operator<(const persistent_betting_market_group_index::internal_type& lhs, const persistent_betting_market_group_index::internal_type& rhs)
{
return lhs.ephemeral_betting_market_group_object < rhs.ephemeral_betting_market_group_object;
}
share_type total_matched_bets_amount;
inline bool operator>(const persistent_betting_market_group_index::internal_type& lhs, const persistent_betting_market_group_index::internal_type& rhs)
{
return !operator<(lhs, rhs);
}
betting_market_id_type get_betting_market_id() const { return ephemeral_betting_market_object.id; }
/**
* @brief This secondary index will allow a reverse lookup of all betting_market_object that happened
*/
class persistent_betting_market_index : public secondary_index
{
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
map< betting_market_id_type, betting_market_object > ephemeral_betting_market_object;
};
struct by_betting_market_id;
typedef multi_index_container<
persistent_betting_market_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_betting_market_id>, const_mem_fun<persistent_betting_market_object, betting_market_id_type, &persistent_betting_market_object::get_betting_market_id> > > > persistent_betting_market_multi_index_type;
typedef generic_index<persistent_betting_market_object, persistent_betting_market_multi_index_type> persistent_betting_market_index;
//////////// bet_object //////////////////
class persistent_bet_object : public graphene::db::abstract_object<persistent_bet_object>
/**
* @brief This secondary index will allow a reverse lookup of all bet_object that happened
*/
class persistent_bet_index : public secondary_index
{
public:
static const uint8_t space_id = bookie_objects;
static const uint8_t type_id = persistent_bet_object_type;
public:
struct internal_type
{
internal_type(const bet_object& other)
: ephemeral_bet_object{other}
{}
bet_object ephemeral_bet_object;
internal_type& operator=(const bet_object& other)
{
ephemeral_bet_object = other;
return *this;
}
// total amount of the bet that matched
share_type amount_matched;
std::vector<operation_history_id_type> associated_operations;
bet_id_type get_bet_id() const { return ephemeral_bet_object.id; }
account_id_type get_bettor_id() const { return ephemeral_bet_object.bettor_id; }
bool is_matched() const { return amount_matched != share_type(); }
friend bool operator==(const internal_type& lhs, const internal_type& rhs);
friend bool operator<(const internal_type& lhs, const internal_type& rhs);
friend bool operator>(const internal_type& lhs, const internal_type& rhs);
bet_object ephemeral_bet_object;
// total amount of the bet that matched
share_type amount_matched;
std::vector<operation_history_id_type> associated_operations;
};
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_modified( const object& after ) override;
map< bet_id_type, internal_type > internal;
};
struct by_bet_id;
struct by_bettor_id;
typedef multi_index_container<
persistent_bet_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_unique<tag<by_bet_id>, const_mem_fun<persistent_bet_object, bet_id_type, &persistent_bet_object::get_bet_id> >,
ordered_unique<tag<by_bettor_id>,
composite_key<
persistent_bet_object,
const_mem_fun<persistent_bet_object, account_id_type, &persistent_bet_object::get_bettor_id>,
const_mem_fun<persistent_bet_object, bool, &persistent_bet_object::is_matched>,
const_mem_fun<persistent_bet_object, bet_id_type, &persistent_bet_object::get_bet_id> >,
composite_key_compare<
std::less<account_id_type>,
std::less<bool>,
std::greater<bet_id_type> > > > > persistent_bet_multi_index_type;
inline bool operator==(const persistent_bet_index::internal_type& lhs, const persistent_bet_index::internal_type& rhs)
{
return lhs.ephemeral_bet_object == rhs.ephemeral_bet_object;
}
typedef generic_index<persistent_bet_object, persistent_bet_multi_index_type> persistent_bet_index;
inline bool operator<(const persistent_bet_index::internal_type& lhs, const persistent_bet_index::internal_type& rhs)
{
return lhs.ephemeral_bet_object < rhs.ephemeral_bet_object;
}
inline bool operator>(const persistent_bet_index::internal_type& lhs, const persistent_bet_index::internal_type& rhs)
{
return !operator<(lhs, rhs);
}
} } } //graphene::bookie::detail
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_event_object, (graphene::db::object), (ephemeral_event_object) )
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_betting_market_group_object, (graphene::db::object), (ephemeral_betting_market_group_object)(total_matched_bets_amount) )
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_betting_market_object, (graphene::db::object), (ephemeral_betting_market_object) )
FC_REFLECT_DERIVED( graphene::bookie::detail::persistent_bet_object, (graphene::db::object), (ephemeral_bet_object)(amount_matched)(associated_operations) )