跳到主要内容

eosio::multi_index

Module: Contracts API / Multi Index Table

Defines EOSIO Multi Index Table. More...

#include <multi_index.hpp>

Public Classes

Name
structconst_iterator

Public Types

Name
typedef std::reverse_iterator< const_iterator >const_reverse_iterator
struct multi_index::const_iterator

Public Functions

Name
multi_index(name code, uint64_t scope)
load_object_by_primary_iterator
nameget_code() const
uint64_tget_scope() const
const_iteratorcbegin() const
const_iteratorbegin() const
const_iteratorcend() const
const_iteratorend() const
const_reverse_iteratorcrbegin() const
const_reverse_iteratorrbegin() const
const_reverse_iteratorcrend() const
const_reverse_iteratorrend() const
const_iteratorlower_bound(uint64_t primary) const
const_iteratorupper_bound(uint64_t primary) const
uint64_tavailable_primary_key() const
template <name::raw IndexName>
auto
get_index()
template <name::raw IndexName>
auto
get_index() const
const_iteratoriterator_to(const T & obj) const
template <typename Lambda >
const_iterator
emplace(name payer, Lambda && constructor)
template <typename Lambda >
void
modify(const_iterator itr, name payer, Lambda && updater)
template <typename Lambda >
void
modify(const T & obj, name payer, Lambda && updater)
const T &get(uint64_t primary, const char * error_msg ="unable to find key") const
const_iteratorfind(uint64_t primary) const
const_iteratorrequire_find(uint64_t primary, const char * error_msg ="unable to find key") const
const_iteratorerase(const_iterator itr)
voiderase(const T & obj)

Detailed Description

template <name::raw TableName,
typename T ,
typename... Indices>
class eosio::multi_index;

Defines EOSIO Multi Index Table.

Template Parameters:

  • TableName - name of the table
  • T - type of the data stored inside the table
  • Indices - secondary indices for the table, up to 16 indices is supported here

EOSIO Multi-Index API provides a C++ interface to the EOSIO database. It is patterned after Boost Multi Index Container. EOSIO Multi-Index table requires exactly a uint64_t primary key. For the table to be able to retrieve the primary key, the object stored inside the table is required to have a const member function called primary_key() that returns uint64_t. EOSIO Multi-Index table also supports up to 16 secondary indices. The type of the secondary indices could be any of:

  • uint64_t
  • uint128_t
  • double
  • long double
  • eosio::checksum256

Example:

#include <eosiolib/eosio.hpp>
using namespace eosio;
class mycontract: contract {
struct record {
uint64_t primary;
uint64_t secondary_1;
uint128_t secondary_2;
checksum256 secondary_3;
double secondary_4;
long double secondary_5;
uint64_t primary_key() const { return primary; }
uint64_t get_secondary_1() const { return secondary_1; }
uint128_t get_secondary_2() const { return secondary_2; }
checksum256 get_secondary_3() const { return secondary_3; }
double get_secondary_4() const { return secondary_4; }
long double get_secondary_5() const { return secondary_5; }
};
public:
mycontract(name receiver, name code, datastream<const char*> ds):contract(receiver, code, ds){}
void myaction() {
auto code = _self;
auto scope = _self;
multi_index<"mytable"_n, record,
indexed_by< "bysecondary1"_n, const_mem_fun<record, uint64_t, &record::get_secondary_1> >,
indexed_by< "bysecondary2"_n, const_mem_fun<record, uint128_t, &record::get_secondary_2> >,
indexed_by< "bysecondary3"_n, const_mem_fun<record, checksum256, &record::get_secondary_3> >,
indexed_by< "bysecondary4"_n, const_mem_fun<record, double, &record::get_secondary_4> >,
indexed_by< "bysecondary5"_n, const_mem_fun<record, long double, &record::get_secondary_5> >
> table( code, scope);
}
}
EOSIO_DISPATCH( mycontract, (myaction) )

Public Types Documentation

typedef const_reverse_iterator

typedef std::reverse_iterator<const_iterator> eosio::multi_index< TableName, T, Indices >::const_reverse_iterator;

struct multi_index::const_iterator

Public Functions Documentation

function multi_index

inline multi_index(
name code,
uint64_t scope
)

load_object_by_primary_iterator

Parameters:

  • code - Account that owns table
  • scope - Scope identifier within the code hierarchy

Precondition: code and scope member properties are initialized

Postcondition:

  • each secondary index table initialized
  • Secondary indices are updated to refer to the newly added object. If the secondary index tables do not exist, they are created.
  • The payer is charged for the storage usage of the new object and, if the table (and secondary index tables) must be created, for the overhead of the table creation.

Constructs an instance of a Multi-Index table.

Notes The [eosio::multi_index](/cdt/latest/reference/Classes/classeosio_1_1multi__index) template has template parameters <[name::raw](/cdt/latest/reference/Classes/structeosio_1_1name#enum-raw) TableName, typename T, typename... Indices>, where:

  • TableName is the name of the table, maximum 12 characters long, characters in the name from the set of lowercase letters, digits 1 to 5, and the "." (period) character and is converted to a eosio::raw - which wraps uint64_t;
  • T is the object type (i.e., row definition);
  • Indices is a list of up to 16 secondary indices.
  • Each must be a default constructable class or struct
  • Each must have a function call operator that takes a const reference to the table object type and returns either a secondary key type or a reference to a secondary key type
  • It is recommended to use the eosio::const_mem_fun template, which is a type alias to the boost::multi_index::const_mem_fun. See the documentation for the Boost const_mem_fun key extractor for more details. Example:
#include <eosiolib/eosio.hpp>
using namespace eosio;
using namespace std;
class addressbook: contract {
struct address {
uint64_t account_name;
string first_name;
string last_name;
string street;
string city;
string state;
uint64_t primary_key() const { return account_name; }
};
public:
addressbook(name self):contract(self) {}
typedef eosio::multi_index< "address"_n, address > address_index;
void myaction() {
address_index addresses(_self, _self.value); // code, scope
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function get_code

inline name get_code() const

Return: Account name of the Code that owns the Primary Table.

Returns the code member property.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
address_index addresses("dan"_n, "dan"_n.value); // code, scope
eosio::check(addresses.get_code() == "dan"_n, "Codes don't match.");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function get_scope

inline uint64_t get_scope() const

Return: Scope id of the Scope within the Code of the Current Receiver under which the desired Primary Table instance can be found.

Returns the scope member property.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
address_index addresses("dan"_n, "dan"_n.value); // code, scope
eosio::check(addresses.get_scope() == "dan"_n.value, "Scopes don't match");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function cbegin

inline const_iterator cbegin() const

Return: An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below

auto itr = addresses.find("dan"_n);
eosio::check(itr == addresses.cbegin(), "Only address is not at front.");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function begin

inline const_iterator begin() const

Return: An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below

auto itr = addresses.find("dan"_n);
eosio::check(itr == addresses.begin(), "Only address is not at front.");
}
}
EOSIO_ABI( addressbook, (myaction) )

function cend

inline const_iterator cend() const

Return: An iterator referring to the past-the-end element in the multi index container.

Returns an iterator referring to the past-the-end element in the multi index container. The past-the-end element is the theoretical element that would follow the last element in the vector. It does not point to any element, and thus shall not be dereferenced.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below

auto itr = addresses.find("dan"_n);
eosio::check(itr != addresses.cend(), "Address for account doesn't exist");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function end

inline const_iterator end() const

Return: An iterator referring to the past-the-end element in the multi index container.

Returns an iterator referring to the past-the-end element in the multi index container. The past-the-end element is the theoretical element that would follow the last element in the vector. It does not point to any element, and thus shall not be dereferenced.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below

auto itr = addresses.find("dan"_n);
eosio::check(itr != addresses.end(), "Address for account doesn't exist");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function crbegin

inline const_reverse_iterator crbegin() const

Return: A reverse iterator pointing to the object_type with the highest primary key value in the Multi-Index table.

Returns a reverse iterator pointing to the object_type with the highest primary key value in the Multi-Index table.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
});
auto itr = addresses.crbegin();
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Last Record ");
itr++;
eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect Second Last Record");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function rbegin

inline const_reverse_iterator rbegin() const

Return: A reverse iterator pointing to the object_type with the highest primary key value in the Multi-Index table.

Returns a reverse iterator pointing to the object_type with the highest primary key value in the Multi-Index table.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
});
auto itr = addresses.rbegin();
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Last Record ");
itr++;
eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect Second Last Record");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function crend

inline const_reverse_iterator crend() const

Return: An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
});
auto itr = addresses.crend();
itr--;
eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Record ");
itr--;
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Record");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function rend

inline const_reverse_iterator rend() const

Return: An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
});
auto itr = addresses.rend();
itr--;
eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Record ");
itr--;
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Record");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function lower_bound

inline const_iterator lower_bound(
uint64_t primary
) const

Parameters:

  • primary - Primary key that establishes the target value for the lower bound search.

Return: An iterator pointing to the object_type that has the lowest primary key that is greater than or equal to primary. If an object could not be found, or if the table does not exist**, it will return the end iterator.

Searches for the object_type with the lowest primary key that is greater than or equal to a given primary key.

Example:

// This assumes the code from the get_index() example below. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
address.zip = 93445;
});
uint32_t zipnumb = 93445;
auto zip_index = addresses.get_index<name("zip")>();
auto itr = zip_index.lower_bound(zipnumb);
eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Lower Bound Record ");
itr++;
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Lower Bound Record");
itr++;
eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function upper_bound

inline const_iterator upper_bound(
uint64_t primary
) const

Parameters:

  • primary - Primary key that establishes the target value for the upper bound search

Return: An iterator pointing to the object_type that has the lowest primary key that is greater than a given primary key. If an object could not be found, or if the table does not exist**, it will return the end iterator.

Searches for the object_type with the lowest primary key that is greater than a given primary key.

Example:

// This assumes the code from the get_index() example below. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
address.zip = 93445;
});
uint32_t zipnumb = 93445;
auto zip_index = addresses.get_index<name("zip")>();
auto itr = zip_index.upper_bound(zipnumb);
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect First Upper Bound Record ");
itr++;
eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function available_primary_key

inline uint64_t available_primary_key() const

Return: An available (unused) primary key value.

Returns an available primary key.

Notes: Intended to be used in tables in which the primary keys of the table are strictly intended to be auto-incrementing, and thus will never be set to custom values by the contract. Violating this expectation could result in the table appearing to be full due to inability to allocate an available primary key. Ideally this method would only be used to determine the appropriate primary key to use within new objects added to a table in which the primary keys of the table are strictly intended from the beginning to be autoincrementing and thus will not ever be set to custom arbitrary values by the contract. Violating this agreement could result in the table appearing full when in reality there is plenty of space left.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
address_index addresses(_self, _self.value); // code, scope
// add to table, first argument is account to bill for storage
addresses.emplace(payer, [&](auto& address) {
address.key = addresses.available_primary_key();
address.first_name = "Daniel";
address.last_name = "Larimer";
address.street = "1 EOS Way";
address.city = "Blacksburg";
address.state = "VA";
});
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function get_index

template <name::raw IndexName>
inline auto get_index()

Template Parameters:

  • IndexName - the ID of the desired secondary index

Return: An index of the appropriate type: Primitive 64-bit unsigned integer key (idx64), Primitive 128-bit unsigned integer key (idx128), 128-bit fixed-size lexicographical key (idx128), 256-bit fixed-size lexicographical key (idx256), Floating point key, Double precision floating point key, Long Double (quadruple) precision floating point key

Returns an appropriately typed Secondary Index.

Example:

#include <eosiolib/eosio.hpp>
using namespace eosio;
using namespace std;
class addressbook: contract {
struct address {
uint64_t account_name;
string first_name;
string last_name;
string street;
string city;
string state;
uint32_t zip = 0;
uint64_t primary_key() const { return account_name; }
uint64_t by_zip() const { return zip; }
};
public:
addressbook(name receiver, name code, datastream<const char*> ds):contract(receiver, code, ds) {}
typedef eosio::multi_index< name("address"), address, indexed_by< name("zip"), const_mem_fun<address, uint64_t, &address::by_zip> > address_index;
void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
uint32_t zipnumb = 93446;
auto zip_index = addresses.get_index<name("zip")>();
auto itr = zip_index.find(zipnumb);
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Record ");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function get_index

template <name::raw IndexName>
inline auto get_index() const

Template Parameters:

  • IndexName - the ID of the desired secondary index

Return: An index of the appropriate type: Primitive 64-bit unsigned integer key (idx64), Primitive 128-bit unsigned integer key (idx128), 128-bit fixed-size lexicographical key (idx128), 256-bit fixed-size lexicographical key (idx256), Floating point key, Double precision floating point key, Long Double (quadruple) precision floating point key

Returns an appropriately typed Secondary Index.

Example:

// This assumes the code from the get_index() example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
address.zip = 93445;
});
uint32_t zipnumb = 93445;
auto zip_index = addresses.get_index<name("zip")>();
auto itr = zip_index.upper_bound(zipnumb);
eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect First Upper Bound Record ");
itr++;
eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function iterator_to

inline const_iterator iterator_to(
const T & obj
) const

Parameters:

  • obj - A reference to the desired object

Return: An iterator to the given object

Returns an iterator to the given object in a Multi-Index table.

Example:

// This assumes the code from the get_index() example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example below
// add dan account to table - see emplace example below
// add additional account - brendan

addresses.emplace(payer, [&](auto& address) {
address.account_name = "brendan"_n;
address.first_name = "Brendan";
address.last_name = "Blumer";
address.street = "1 EOS Way";
address.city = "Hong Kong";
address.state = "HK";
address.zip = 93445;
});
auto user = addresses.get("dan"_n);
auto itr = address.find("dan"_n);
eosio::check(iterator_to(user) == itr, "Invalid iterator");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

Warning: the interator_to can have undefined behavior if the caller passes in a reference to a stack-allocated object rather than the reference returned by get or by dereferencing a const_iterator.

function emplace

template <typename Lambda >
inline const_iterator emplace(
name payer,
Lambda && constructor
)

Parameters:

  • payer - Account name of the payer for the Storage usage of the new object
  • constructor - Lambda function that does an in-place initialization of the object to be created in the table

Return: A primary key iterator to the newly created object

Precondition: A multi index table has been instantiated

Postcondition:

  • A new object is created in the Multi-Index table, with a unique primary key (as specified in the object). The object is serialized and written to the table. If the table does not exist, it is created.
  • Secondary indices are updated to refer to the newly added object. If the secondary index tables do not exist, they are created.
  • The payer is charged for the storage usage of the new object and, if the table (and secondary index tables) must be created, for the overhead of the table creation.

Adds a new object (i.e., row) to the table.

Exception - The account is not authorized to write to the table.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
address_index addresses(_self, _self.value); // code, scope
// add to table, first argument is account to bill for storage
addresses.emplace(_self, [&](auto& address) {
address.account_name = "dan"_n;
address.first_name = "Daniel";
address.last_name = "Larimer";
address.street = "1 EOS Way";
address.city = "Blacksburg";
address.state = "VA";
});
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function modify

template <typename Lambda >
inline void modify(
const_iterator itr,
name payer,
Lambda && updater
)

Parameters:

  • itr - an iterator pointing to the object to be updated
  • payer - account name of the payer for the storage usage of the updated row
  • updater - lambda function that updates the target object

Precondition:

  • itr points to an existing element
  • payer is a valid account that is authorized to execute the action and be billed for storage usage.

Postcondition:

  • The modified object is serialized, then replaces the existing object in the table.
  • Secondary indices are updated; the primary key of the updated object is not changed.
  • The payer is charged for the storage usage of the updated object.
  • If payer is the same as the existing payer, payer only pays for the usage difference between existing and updated object (and is refunded if this difference is negative).
  • If payer is different from the existing payer, the existing payer is refunded for the storage usage of the existing object.

Modifies an existing object in a table.

Exceptions: If called with an invalid precondition, execution is aborted.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example
// add dan account to table - see emplace example

auto itr = addresses.find("dan"_n);
eosio::check(itr != addresses.end(), "Address for account not found");
addresses.modify( itr, account payer, [&]( auto& address ) {
address.city = "San Luis Obispo";
address.state = "CA";
});
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function modify

template <typename Lambda >
inline void modify(
const T & obj,
name payer,
Lambda && updater
)

Parameters:

  • obj - a reference to the object to be updated
  • payer - account name of the payer for the storage usage of the updated row
  • updater - lambda function that updates the target object

Precondition:

  • obj is an existing object in the table
  • payer is a valid account that is authorized to execute the action and be billed for storage usage.

Postcondition:

  • The modified object is serialized, then replaces the existing object in the table.
  • Secondary indices are updated; the primary key of the updated object is not changed.
  • The payer is charged for the storage usage of the updated object.
  • If payer is the same as the existing payer, payer only pays for the usage difference between existing and updated object (and is refunded if this difference is negative).
  • If payer is different from the existing payer, the existing payer is refunded for the storage usage of the existing object.

Modifies an existing object in a table.

Exceptions: If called with an invalid precondition, execution is aborted.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example
// add dan account to table - see emplace example

auto itr = addresses.find("dan"_n);
eosio::check(itr != addresses.end(), "Address for account not found");
addresses.modify( *itr, payer, [&]( auto& address ) {
address.city = "San Luis Obispo";
address.state = "CA";
});
eosio::check(itr->city == "San Luis Obispo", "Lock arf, Address not modified");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function get

inline const T & get(
uint64_t primary,
const char * error_msg ="unable to find key"
) const

Parameters:

  • primary - Primary key value of the object.

Return: A constant reference to the object containing the specified primary key.

Retrieves an existing object from a table using its primary key.

Exception - No object matches the given key.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example
// add dan account to table - see emplace example

auto& user = addresses.get("dan"_n);
eosio::check(user.first_name == "Daniel", "Couldn't get him.");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

Warning:

Avoid the common pitfall of copy-assigning the T& reference returned to a stack-allocated local variable and then passing that into modify of the multi-index. The most common mistake is when the local variable is defined as auto typename, instead it should be of type auto& or decltype(auto).

function find

inline const_iterator find(
uint64_t primary
) const

Parameters:

  • primary - Primary key value of the object

Return: An iterator to the found object which has a primary key equal to primary OR the end iterator of the referenced table if an object with primary key primary is not found.

Search for an existing object in a table using its primary key.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example
// add dan account to table - see emplace example

auto itr = addresses.find("dan"_n);
eosio::check(itr != addresses.end(), "Couldn't get him.");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

function require_find

inline const_iterator require_find(
uint64_t primary,
const char * error_msg ="unable to find key"
) const

Parameters:

  • primary - Primary key value of the object
  • error_msg - error message if an object with primary key primary is not found.

Return: An iterator to the found object which has a primary key equal to primary OR throws an exception if an object with primary key primary is not found.

Search for an existing object in a table using its primary key.

function erase

inline const_iterator erase(
const_iterator itr
)

Parameters:

  • itr - An iterator pointing to the object to be removed

Return: For the signature with [const_iterator](/cdt/latest/reference/Classes/structeosio_1_1multi__index_1_1const__iterator), returns a pointer to the object following the removed object.

Precondition: itr points to an existing element

Postcondition:

  • The object is removed from the table and all associated storage is reclaimed.
  • Secondary indices associated with the table are updated.
  • The existing payer for storage usage of the object is refunded for the table and secondary indices usage of the removed object, and if the table and indices are removed, for the associated overhead.

Remove an existing object from a table using its primary key.

Exceptions: The object to be removed is not in the table. The action is not authorized to modify the table. The given iterator is invalid.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
// create reference to address_index - see emplace example
// add dan account to table - see emplace example

auto itr = addresses.find("dan"_n);
eosio::check(itr != addresses.end(), "Address for account not found");
addresses.erase( itr );
eosio::check(itr != addresses.end(), "Everting lock arf, Address not erased properly");
}
}
EOSIO_ABI( addressbook, (myaction) )

function erase

inline void erase(
const T & obj
)

Parameters:

  • obj - Object to be removed

Precondition: obj is an existing object in the table

Postcondition:

  • The object is removed from the table and all associated storage is reclaimed.
  • Secondary indices associated with the table are updated.
  • The existing payer for storage usage of the object is refunded for the table and secondary indices usage of the removed object, and if the table and indices are removed, for the associated overhead.

Remove an existing object from a table using its primary key.

Exceptions: The object to be removed is not in the table. The action is not authorized to modify the table. The given iterator is invalid.

Example:

// This assumes the code from the constructor example. Replace myaction() {...}

void myaction() {
auto itr = addresses.find("dan"_n);
eosio::check(itr != addresses.end(), "Record is not found");
addresses.erase(*itr);
itr = addresses.find("dan"_n);
eosio::check(itr == addresses.end(), "Record is not deleted");
}
}
EOSIO_DISPATCH( addressbook, (myaction) )

Updated on 2022-12-05 at 15:38:07 +0000