高级EOS系列 - 第3部分 - 二级索引

欢迎回到高级EOS开发系列,在这里我将讨论教程或课程很少涉及的高级技术和功能。本系列的目的是汇集您在EOS网络上作为分布式应用程序开发人员完成技能所需的缺失部分。每个帖子都是按难度排序的,所以如果您想要概述,我建议您从第1部分开始,逐步完成。这些示例的完整代码可以在GitHub上找到

MitchPierias/Advanced-EOS-Examples

由于这些是高级或扩展的主题,我很严肃地假设您已经了解基础知识,并希望进一步了解您的知识。出于这个原因,这些文章中共享的代码将只是为了讨论的目的而简明扼要。

主要索引

到目前为止,您应该知道如何使用struct在EOS中定义多索引表,但为了完整起见,我们简要介绍一下我们的基本表定义。

定义struct

我们将首先定义我们struct及它所需的primary_key函数,这是我们调用时使用的索引find(KEY) 。现在让我们使用用户account_name的独特性,并在下一章中介绍一种更通用的方法。

// @abi table items i64
struct Item {
  account_name      id;
  string            name;
  uint64_t          attack;
  account_name      owner;

  auto primary_key() const { return id; };
  EOSLIB_SERIALIZE(Item, (id)(name)(attack)(owner));
};
创建表

现在我们已经声明了我们的struct。我们可以使用multi_index<TABLE_NAME, TABLE_STRUCT>EOS库中的方法定义我们的多索引表;

typedef multi_index<N(items), Item> items_table;

在我们之后typedef,我们可以简单地定义一个引用,然后在我们的构造函数中初始化我们的表,或者我们可以根据需要在每个函数中初始化一个引用。

二级索引

让我们通过添加二级索引来扩展我们表的功能,以便各自所有者获取项目。我们的Item结构现在看起来像这样:

// @abi table items i64
struct Item {
  auto              id;
  string            name;
  uint64_t          attack;
  account_name      owner;

  auto primary_key() const { return id; };
  uint64_t get_owner() const { return owner; };
  EOSLIB_SERIALIZE(Item, (id)(name)(attack)(owner));
};

我在索引primary_key下面添加一行unit64_t get_owner() const { return owner; };。此函数只返回owner调用时的值。

定义二级索引

让我们在多索引表中将其定义为二级索引,以便我们以后可以访问它;

typedef multi_index<N(items), Item, indexed_by<N(byowner), const_mem_fun<Item, uint64_t, &Item::get_owner>>> item_table;

不要让上面的代码吓到你,这只是我们之前的声明,还有一个额外的论点。

indexed_by<N(byowner), const_mem_fun<Item, uint64_t, &Item::get_owner>>

这是定义我们的二级索引的代码。我们使用indexed_by<INDEX_NAME, LOOKUP_FUNCTION_DEFINITION>来指定索引byowner

  • INDEX_NAME; 可以是你喜欢的任何东西,不需要在语法上匹配我们的函数get_owner,只需记住它是我们将在后面的操作中用来访问二级索引的名称。
  • LOOKUP_FUNCTION_DEFINITION:cons_mem_fun<STRUCT, RETURN_VALUE, LOOKUP_FUNCTION>在我们的示例中看起来像构造我们的二级索引函数并将其分配给我们的索引定义的函数。
使用二级索引

所以我们已经为我们的项目编写了索引owner,但是我们如何使用索引来查找特定用户拥有的项目?为此我们将步入一个动作并使用多索引表方法get_index<INDEX_NAME>(),让我们创建一个名为inventory获取用户项的动作。

// @abi action
void inventory(const account_name account) {
  item_table items(_self, _self);
  auto playerItems = items.get_index<N(byowner)>();
  auto iter = playerItems.lower_bound(account);
  while (iter != playerItems.end()) {
    print("Item ", iter->name);
    iter++;
  }
}

让我们突破以下几行,深入研究它的责任;

auto playerItems = items.get_index<N(byowner)>();

这一行使用get_index我们item_table实例的函数来获取我们之前定义的索引。请注意,我们使用N(byowner)前面指定的相同名称来引用我们正在寻找的索引。

这是二级索引,现在我们有了索引,我们可以执行通常使用primary_index执行的所有功能。在这个例子中,我们使用lower_bound,您也可以使用findgetupper_boundbegin,或end以满足您的特定用例。

原文链接

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值