0

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.

1
  • Try different type of key (eg. uint64_t) instead of string. – conr2d Jul 9 '20 at 15:07
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.