EOS 学習メモ:セカンダリインデックス編

in #eos6 years ago (edited)

dg1uxga7sv.jpg

EOS 学習メモ:永続データハンドリング編 の続き。

EOS では、前回つくったような table にインデックスが最大 16 個貼れるらしい。前回は pk を定義しただけなので、今回は別の field に対してセカンダリインデックスを貼ってみる。セカンダリインデックスと言われると、B-tree の気持ちを知らずに乱暴ばかりしていた若かりし日々を思い出(ry

まず、セカンダリインデックスを貼るための field を person struct に追加する。people table にデータが残っていると変更できないらしいので、残っているデータがあれば、コンテナ上で以下のように erase を実行して全て削除する。前回の手順通りに進めていれば何もデータは残っていないはずなので、何もする必要はない。

 $ cleos push action addressbook erase '["alice"]' -p alice@active



削除できたらaddressbook contract を このように 修正する。変更点をざっくりまとめると以下のようになる。

  • person struct に age field を追加
  • age field にセカンダリインデックスを貼る
  • 上記に合わせて upsert action handler を修正

わざわざ age field を追加しているのは、セカンダリインデックスは数値型の field に貼る必要があるから。

ということで、修正した addressbook contract をコンテナ上に持っていく。

 $ docker cp contracts/addressbook-with-secondary-index/addressbook.cpp eos:/tmp/contracts/addressbook/addressbook.cpp



コンテナに接続。

 $ docker exec -it eos bash



以降、コンテナ上で作業を進める。

修正した addressbook.cpp をコンパイルする。

 $ cd /tmp/contracts/addressbook
 $ eosio-cpp -o addressbook.wasm addressbook.cpp --abigen



addressbook account に対してデプロイする。

 $ cleos set contract addressbook . -p addressbook@active
 Reading WASM from /tmp/contracts/addressbook/addressbook.wasm...
 Publishing contract...
 executed transaction: 9950707240ee5f09155d1421815830b42f15ca3ffcd2d25183aacad50521d7ea  6344 bytes  4651 us
 #         eosio <= eosio::setcode               {"account":"addressbook","vmtype":0,"vmversion":0,"code":"0061736d0100000001b6011c60027f7e0060087f7e...
 #         eosio <= eosio::setabi                {"account":"addressbook","abi":"0e656f73696f3a3a6162692f312e31000305657261736500010475736572046e616d...



age つきで alice のデータを登録する。チュートリアル によると、alice は 9 歳らしい。

 $ cleos push action addressbook upsert '["alice", "alice", "liddell", 9, "123 drink me way", "wonderland", "amsterdam"]' -p alice@active
 executed transaction: a5d9a7918064340832a4d2af7074a2a735a3b108c5b3779ef0e7b9021a5e84f4  160 bytes  8272 us
 #   addressbook <= addressbook::upsert          {"user":"alice","first_name":"alice","last_name":"liddell","age":9,"street":"123 drink me way","city...



次は bobbob は 49 歳らしい笑

 $ cleos push action addressbook upsert '["bob", "bob", "is a guy", 49, "doesnt exist", "somewhere", "someplace"]' -p bob@active
 executed transaction: 31d99fcc7327e058b6de7fc4d63d9d0e245ed88796c6877bc5c4460cd2a75207  160 bytes  6918 us
 #   addressbook <= addressbook::upsert          {"user":"bob","first_name":"bob","last_name":"is a guy","age":49,"street":"doesnt exist","city":"som...



データが登録できたので、age field に貼ったセカンダリインデックスを利用してデータを取得してみる。

age field に貼ったセカンダリインデックスは 2 つ目のインデックス(1 つ目は pk だと思われる)なので、--index には 2 を指定し、age の値が 10 以下であるデータを取得する。

 $ cleos get table addressbook addressbook people --upper 10 --key-type i64 --index 2
 {
   "rows": [{
       "key": "alice",
       "first_name": "alice",
       "last_name": "liddell",
       "age": 9,
       "street": "123 drink me way",
       "city": "wonderland",
       "state": "amsterdam"
     }
   ],
   "more": false
 }



9 歳の alice は条件を満たし、49 歳の bob は条件を満たさないので、取得できたのは alice のデータだけである。

次は age の値が 50 以下であるデータを取得する。今度は bob も条件を満たす。

 $ cleos get table addressbook addressbook people --upper 50 --key-type i64 --index 2
 {
   "rows": [{
       "key": "alice",
       "first_name": "alice",
       "last_name": "liddell",
       "age": 9,
       "street": "123 drink me way",
       "city": "wonderland",
       "state": "amsterdam"
     },{
       "key": "bob",
       "first_name": "bob",
       "last_name": "is a guy",
       "age": 49,
       "street": "doesnt exist",
       "city": "somewhere",
       "state": "someplace"
     }
   ],
   "more": false
 }



無事、alicebob のデータが取得できた。

今回はここまで。

Sort:  

Thanks for using eSteem!
Your post has been voted as a part of eSteem encouragement program. Keep up the good work! Install Android, iOS Mobile app or Windows, Mac, Linux Surfer app, if you haven't already!
Learn more: https://esteem.app
Join our discord: https://discord.gg/8eHupPq

Congratulations @m0t0k1ch1! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You published more than 20 posts. Your next target is to reach 30 posts.

Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word STOP

To support your work, I also upvoted your post!

Support SteemitBoard's project! Vote for its witness and get one more award!