EOS搬运工之按主键查找表记录的RPC接口

按主键查找表中记录的RPC接口

现在的EOS有命令行方式显示合约中表的数据的命令,而且显示的是全表记录,默认最多只能显示10条,这个可以通过cleos get table命令的–limit参数临时修改。EOS没有按条件查找记录的命令,也没有对应的RPC接口。

RPC接口调用的函数源码:

// rpc参数对应的结构体
struct table_record_params {
          string contract_account; // 部署了合约的账号
          string table;            // 表名
          string data;             // 查找条件,如:id=xidx
         };

fc::variant query_table(const table_record_params& str_params){
    const auto& c_plugin = _app.get_plugin<chain_plugin>();
    const auto& db = c_plugin.chain().db();

    const auto& code_account = db.get<account_object, by_name>( eosio::string_to_name(str_params.contract_account.c_str()) );

    const fc::microseconds abi_serializer_max_time(10 * 1000);

    vector<fc::variant> rows;
    abi_def abi;
    if( abi_serializer::to_abi(code_account.abi, abi) ) {
        abi_serializer abis( abi, abi_serializer_max_time );

        // make_tupl的3个参数,按顺序分别为:部署了操作表数据合约的账号(比如插入记录、删除记录合约)、表域(即表的scope)、表名
        const auto* t_id = db.find<chain::table_id_object, chain::by_code_scope_table>(boost::make_tuple( eosio::string_to_name(str_params.contract_account.c_str()), N(tbsp), eosio::string_to_name(str_params.table.c_str()) ));
        if (t_id != nullptr) {
            const auto &idx = db.get_index<key_value_index, by_scope_primary>();
            vector<string> vec_con;
            boost::split( vec_con, str_params.data , boost::is_any_of( "=" ), boost::token_compress_on );
            string str_data = vec_con.size() >= 2 ? vec_con[1] : vec_con[0];
            // make_tuple的第2个参数为要查询记录的主键值
            auto it = idx.find(boost::make_tuple( t_id->id, eosio::string_to_name(str_data.c_str()) ));
            if ( it != idx.end() ) {
                vector<char> data;
                eosio::chain_apis::read_only::copy_inline_row(*it, data);
                          rows.emplace_back(abis.binary_to_variant(abis.get_table_type(eosio::string_to_name(str_params.table.c_str())), data, abi_serializer_max_time));
            }
        }
    }

  return fc::variant(rows);
}

实现的函数体不长,但研究出来也是耗费了一番功夫,我的思路是通过查看cleos get account和cleos get table两个命令的代码,整理出来主键记录查找逻辑。因为,get account是查询特定一个记录,而get table是查询全表记录,一个是有条件查询,一个是无条件查询,正好概括了查找的全部场景,所以,从这里面肯定能找出一些端倪。

改进的地方:现在只能由主键来查,所以只能查询一条记录,可以增强按非主键的字段来查询,这样便能实现查询多条记录。从EOS对table的支持来看,有二级索引的功能,有这个支持,实现按非主键查询也是可能的。但目前业务上按主键查询,能满足要求,暂时就不花精力研究二级索引查询了,转去下一个难点攻克,待以后增加了再来更新文章也不迟。

【本章完】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值