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

m0t0k1ch1(48)
Published in
#eos
Words
314
Reading
2 min
8y
Listen to this post
~2 min

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...



次は bob。bob は 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
 }



無事、alice と bob のデータが取得できた。

今回はここまで。