EOS.IO Asked by iambaeba1 on August 20, 2021
After program is terminated, user defined object cannot be loaded to chainbase::database.
my code is followed.
enum my_type {
my_inx01_object_type
};
namespace eosio { namespace chain {
using boost::multi_index_container;
using namespace boost::multi_index;
class my_inx01_object : public chainbase::object<my_inx01_object_type, my_inx01_object> {
OBJECT_CTOR(my_inx01_object)
id_type id;
string action_sign;
string trx_id;
};
struct by_sign;
using my_inx01_index = chainbase::shared_multi_index_container<
my_inx01_object,
indexed_by<
ordered_unique<
tag<by_id>,
member<my_inx01_object, my_inx01_object::id_type, &my_inx01_object::id>
>,
ordered_unique<
tag<by_sign>,
BOOST_MULTI_INDEX_MEMBER(my_inx01_object, string, action_sign)
>
>
>;
} } // End of namespace eosio::chain
CHAINBASE_SET_INDEX_TYPE(eosio::chain::my_inx01_object, eosio::chain::my_inx01_index)
FC_REFLECT(eosio::chain::my_inx01_object, (action_sign)(trx_id))
void internal_db_test3()
{
uint32_t nRet;
chainbase::database db(
"/home/my/Documents/default_boot/blockchain_debug/data/",
database::read_write, //database::read_only,
1024*1024*1); // 1 mb
db.add_index< my_inx01_index >();
// insert
string strTrxId = "TRXID0000000000000000000000000000000000000000000000000000000001";
string strActionSign = "SIGNP0123456789012345678901234567890123456789012345678901234567";
// select
const my_inx01_object *result = db.find<my_inx01_object, by_sign>(strActionSign);
db.create<my_inx01_object>(
[&](auto &a) {
a.action_sign = strActionSign;
a.trx_id = strTrxId;
}
);
// select
const my_inx01_object *result2 = db.find<my_inx01_object, by_sign>(strActionSign);
}
void internal_db_test4()
{
uint32_t nRet;
chainbase::database db(
"/home/my/Documents/default_boot/blockchain_debug/data/",
database::read_write, //database::read_only,
1024*1024*1); // 1 mb
db.add_index< my_inx01_index >();
// insert
string strTrxId = "TRXID0000000000000000000000000000000000000000000000000000000001";
string strActionSign = "SIGNP0123456789012345678901234567890123456789012345678901234567";
// select
const my_inx01_object *result = db.find<my_inx01_object, by_sign>(strActionSign);
}
int main(int argc, char** argv)
{
internal_db_test3();
internal_db_test4();
return 1;
}
Above code is not problem that execute once. internal_db_test3() and internal_db_test4() are ok.
Code is modified and the program is restarted
int main(int argc, char** argv)
{
//internal_db_test3();
internal_db_test4();
return 1;
}
// select
const my_inx01_object *result = db.find<my_inx01_object, by_sign>(strActionSign);
==> result is null !!
But I don’t understand why result is null.
I found the solution. The reference code is followed by boost manual. (https://www.boost.org/doc/libs/1_73_0/libs/multi_index/example/ip_allocator.cpp)
Boost.MultiIndex supports special allocators such as those provided by Boost.Interprocess, which allows for multi_index_containers to be placed in shared memory.
Chainbase database use shared memory. If user defined object has string type, string type must be changed to shared_string type.
namespace eosio { namespace chain {
using boost::multi_index_container;
using namespace boost::multi_index;
class my_inx02_object : public chainbase::object<my_inx02_object_type, my_inx02_object> {
OBJECT_CTOR(my_inx02_object, (action_sign)(trx_id))
id_type id;
shared_string action_sign;
shared_string trx_id;
};
struct by_sign;
using my_inx02_index = chainbase::shared_multi_index_container<
my_inx02_object,
indexed_by<
ordered_unique<
tag<by_id>,
member<my_inx02_object, my_inx02_object::id_type, &my_inx02_object::id>
>,
ordered_unique<
tag<by_sign>,
BOOST_MULTI_INDEX_MEMBER(my_inx02_object, shared_string, action_sign)
>
>
>;
} } // End of namespace eosio::chain
CHAINBASE_SET_INDEX_TYPE(eosio::chain::my_inx02_object, eosio::chain::my_inx02_index)
FC_REFLECT(eosio::chain::my_inx02_object, (action_sign)(trx_id))
void internal_db_test5()
{
chainbase::database db(
"/home/my/Documents/default_boot/blockchain_debug/data/",
database::read_write, //database::read_only,
1024*1024*1); // 1 mb
db.add_index< my_inx02_index >();
string strTrxId = "TRXID0000000000000000000000000000000000000000000000000000000001";
string strActionSign = "SIGNP0123456789012345678901234567890123456789012345678901234567";
shared_string ssActionSign( shared_string::allocator_type(db.get_segment_manager()) );
ssActionSign.assign(strActionSign.c_str(), strActionSign.length());
// select
const my_inx02_object *result = db.find<my_inx02_object, by_sign>(ssActionSign);
if ( result != nullptr) {
string strData_action_sign = result->action_sign.data();
string strData_TrxId = result->trx_id.data();
}
db.create<my_inx02_object>(
[&](auto &a) {
a.action_sign.assign( strActionSign.c_str(), strActionSign.length() );
a.trx_id.assign( strTrxId.c_str(), strTrxId.length() );
}
);
// select
const my_inx02_object *result2 = db.find<my_inx02_object, by_sign>(ssActionSign);
}
int main(int argc, char** argv)
{
internal_db_test5();
return 1;
}
After the program is shutdowned and restarted, you can successfuly access shared_string types.
Answered by iambaeba1 on August 20, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP