摘要:比如,第一張圖中,如果傳入的參數為,那就可以找出所有為的數據了,放入迭代器里。每次小的遍歷結束是,迭代器,表示繼續訪問迭代器中的下一行。
上一章我們學習了對智能合約開發來說至關重要的第一步:
知道了RAM、multi_index和EOS數據庫各是什么以及它們之間的關系;
知道了multi_index是內存數據庫的入口;
了解了multi_index內部的結構長什么樣子;
今天這章,主要介紹multi_index的相關操作,趁機鞏固一波上一章學習到的理論知識。
摘要上一章說到multi_index的概念——多索引容器,multi_index容器的內部結構可以類比成傳統數據庫里的一張表,只不過這張表只有一列,每一行都是一個struct結構體。
這一章就要向大家介紹,如何具體使用multi_index。
primary keys還是上一章中的例子:
multi_index的容器(表)里每一行都是上面的struct結構體,并且都是按照主鍵升序排列。所以每一個multi_index中會有一個默認索引,也就是主鍵。如上圖,就是按照主鍵(pkey)升序排列的。
uint64_t primary_key() const { return pkey; }
一般而言,在struct結構體中會聲明一行獲得主鍵的方法primary_key(),這里定義了主鍵類型為uint64_t,返回結構體中的pkey字段,即pkey這個字段就是整個結構體的主鍵。
自定義索引既然叫multi_index,肯定不只可以根據主鍵進行索引,事實上,我們還可以自定義索引。例如可以在結構體中定義如下方法:
account_name get_customer() const { return customer; }
這就是我們自定義的索引。仿照之前的primary_key()可以看到,這個方法返回值的類型為account_name,返回的字段為customer。當然自定義的索引并不一定要返回結構體中的某個字段的變量,也可以將變量之間的運算結果作為索引。
這里先貼上結構體的完整表達,方便下面介紹如何使用多索引:
struct service_struct { uint64_t pkey; account_name customer; Date date; uint32_t odometer; auto primary_key() const {return pkey;} account_name get_customer() const {return customer;} EOSLIB_SERIALIZE(service_struct,( pkey )( customer )( date )( odometer )) } typedef eosio::multi_index> > customer_index;
解釋一下,使用上面的方式來定義索引,eosio::multi_index<...>的參數解釋如下:
service : multi_index容器的表名(如上圖)
service_struct : 智能合約重定義的struct結構體名稱,也可以理解成表中的一行記錄;
indexed_by<...> :
N(bycustomer) : 給索引起個名字 - bycustomer
const_mem_fun<...> :
account_name : 索引的類型
&service_struct::get_customer:通過service_struct結構體中的get_customer函數獲得(索引)
通過上述表達,就可以再生成一張按customer為索引的表bycustomer(見本文第一張圖)。左邊是按照主鍵索引的原表service,右邊的表就是我們按照customer的索引生成的新表(按customer從小到大進行排列),可以看到新表內的行內容和之前是一行的(見虛線指向原表),只不過按照customer字段進行了重新排列。
這里定義了customer_index類型,這樣以后就可以直接用這個類型去初始化真正的multi_index表。
迭代器上一章我們介紹過迭代器,可以把迭代器想象成一個電梯,通過在索引中上下滑動來定位數據。接著上面介紹的自定義索引comstomer_index:
account_name customer_acct = eosio::chain::string_to_name(customer_name); auto cust_itr = customer_index.find(customer_acct);
通過上述代碼,我們就可以找到bycustomer表中,customer為某個特定值的所有行(結構體)了。比如,第一張圖中,如果傳入的參數為"bob",那就可以找出所有customer為bob的數據了,放入迭代器里。通過迭代器就可以逐條獲取我們想要的數據信息。
得到了迭代器之后,咱們再來看看怎么使用迭代器:
while(cust_itr != service.end() && cust_itr -> customer == customer_acct) { // code to execute cust_itr++; }
其中cust_itr != service.end()表示迭代器并沒有走到service表的結尾,&&之后也很容易看懂,再篩選customer的值。每次小的遍歷結束是,迭代器+1,表示繼續訪問迭代器中的下一行。
索引和迭代器如何配合工作通過上面的介紹,大家應該就可以理清multi_index和迭代器是如何配合工作的:
i通過multi_index可以得到一張按照特定字段索引的表,再通過對索引設置一些條件,就可以篩選得到一些迭代器,再通過對迭代器的遍歷,就可以訪問我們想要訪問的數據了。multi_index的初始化
上文關于multi_index多與定義有關,現在終于要開始實例化multi_index了。
multi_index(uint64_t code, uint64_t scope)
在上面的初始化(實例化)的語句中,可以看到有兩個參數:
code -擁有這張multi_index表的賬戶,該賬戶擁有對合約數據的讀寫權限;
scope - 用戶賬戶名下的區域??梢栽赾ode下定義多個scope,把屬于不同scope的表隔離開;
這里的code和scope,都是用來為表建立訪問權限的。
所以要想初始化上面的customer_index,可以使用:
// customer_index 就是之前 typedef 定義的類型 // bycustomer就是新表 // _self就是當前調用方法的賬戶 customer_index bycustomer(_self, _self);添加 - emplace
這里順便說一下find,multi_index使用.find來查詢,代碼接上往下寫:
void demo::create(const uint64_t id, const account_name cust_acct, const Date date, const uint32_t odometer) { // 找出特定值的customer的數據 // 這里的auto相當于其他語言中的var,聲明變量時不指定類型 auto itr = bycustomer.find(cust_acct); // 查詢customer = cust_acct的記錄并要求該記錄不存在 // 因為primary_key不能重復 // 所以插數據之前先查詢一下,保證不重復 eosio_assert(itr == profile.end(), "Account already exists"); // 往索引里添加記錄 bycustomer.emplace(cust_acct, [&](auto& c)) { c.pkey = id; c.customer = cust_acct; c.date = date; c.odometer = odometer; } }
其中[&](auto& c)是c11之后一種新的lambda表達式,有興趣的同學可以自行深入了解,這里簡單介紹一下,這個表達式大概表示:
除了該函數已有的參數,其他的參數例如 id, date, odometer這些,都是在上層的作用域中通過引用的形式傳入函數內。其中auto我們之前說過,表示不限制類型,但是也為引用。
看懂了添加記錄,其他諸如刪、改、查的操作也就不難看懂了,大家可以去官網查看相關例子:
https://eosio-cpp.readme.io/d...
結束語本章我們學習了:
如何自定義索引;
如何生成以及使用迭代器;
索引和迭代器是如何配合使用的;
multi_index的相關操作
希望大家學完之后可以去官網繼續補充刪、改、查的相關例子,以達到舉一反三的效果。下面幾篇我們將正式了解EOS智能合約開發的二三事。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/24222.html
摘要:允許智能合約定義自己的私有數據庫表。有了多級索引,智能合約就具備了操作類似數據庫模塊的功能。因此雖然只有一列,但是的靈活性絲毫不亞于傳統的數據表。 上一章我們學習了開發智能合約之前需要知道的必要概念: 什么是webAssembly以及它在智能合約上下游中的位置; 什么是ABI以及怎樣使用eosiocpp工具產生ABI和wasm、wast hello智能合約的簡單入門:部署和調用 ...
摘要:這里的是封裝的,返回中,當前索引的迭代器之后遍歷該迭代器,就可以獲得所有某個特定值的所有數據。 上一章我們細致地學習了 索引和迭代器的關系; 如何生成和使用索引以及迭代器 介紹了multi_index的相關操作 相信大家對multi_index已經有了比較全面的理論理解以及掌握了一些基礎的操作。這一章將會教大家如何完整地構建一個智能合約,并在合約中直觀地操作multi_inde...
摘要:需要對構造函數進行命名和配置,以使用我們之前定義的結構。我們的構造函數傳遞的范圍參數是正在部署合約的區塊鏈上的帳戶。此方法接受兩個參數,即此記錄的范圍和回調函數?;卣{函數用于處理表的修改。但是如果用戶想要完全刪除記錄呢請看的數據持久性下。 本教程假定你已經完成了EOS開發從智能合約開始。 要了解數據持久性,請編寫一個簡單的智能合約,作為地址記錄。雖然這個用例由于各種原因而不太適合作為生...
閱讀 2706·2023-04-26 02:02
閱讀 2571·2023-04-25 20:38
閱讀 4098·2021-09-26 09:47
閱讀 3092·2021-09-10 10:50
閱讀 3765·2021-09-07 09:58
閱讀 3326·2019-08-30 15:54
閱讀 2694·2019-08-30 15:54
閱讀 1918·2019-08-29 17:03