Instantiate table
Overview
This guide provides instructions to instantiate a multi-index table.
Procedure
Complete the following steps to instantiate a multi-index table datatable
.
1. Preparation And Initialization
Include the inery.hpp
header and use the using
directive to access the inery
namespace.
#include <inery/inery.hpp>
using namespace inery;
2. Define The Table Data Structure
Define the data structure for the multi-index table.
struct [[inery::table]] data_structure {
};
Add the data structure data members. Each data member corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding data member for the primary key field must store unique values. In this case it is the test_primary
data member of type inery::name
.
// the data structure which defines each row of the table
struct [[inery::table]] data_structure {
+ // this data member stores a name for each row of the multi-index table
+ name test_primary;
+ // additional data stored in table row, e.g. an uint64_t type data
+ uint64_t datum;
};
3. Define The Primary Index
Add the definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and must be named primary_key()
, otherwise the compiler (inery-cpp) will generate an error saying it can not find the field to use as the primary key:
// the data structure which defines each row of the table
struct [[inery::table]] data_structure {
// this data member stores a name for each row of the multi-index table
name test_primary;
// additional data stored in table row
uint64_t datum;
+ // mandatory definition for primary key getter
+ uint64_t primary_key( ) const { return test_primary.value; }
};
Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double.
4. Define A Multi-Index Type Alias
For ease of use, define a type alias data_structure_t
based on the inery::multi_index
template type, parametarized with a random name "datatable"
and the data_structure
data structure. The names must adhere to INERY
account name restrictions.
// the data structure which defines each row of the table
struct [[inery::table]] data_structure {
// this data member stores a name for each row of the multi-index table
name test_primary;
// additional data stored in table row
uint64_t datum;
// mandatory definition for primary key getter
uint64_t primary_key( ) const { return test_primary.value; }
};
+ typedef inery::multi_index<"datatable"_n, data_structure> data_structure_t;
5. Instantiate The Multi-Index Table
Declare the datatable
multi-index table as a data member of type data_structure_t
.
// the data structure which defines each row of the table
struct [[inery::table]] data_structure {
// this data member stores a name for each row of the multi-index table
name test_primary;
// additional data stored in table row
uint64_t datum;
// mandatory definition for primary key getter
uint64_t primary_key( ) const { return test_primary.value; }
};
typedef inery::multi_index<"datatable"_n, data_structure> data_structure_t;
+ data_structure_t datatable;
6. Initialize The Multi-Index Table Instance
Initialize the data member datatable
by passing to its constructor these two values: receiver
for the code
parameter and receiver.value
for the scope
parameter. These two parameters combined with table name "datatable"
provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the datatable
data member in the value contract constructor
// contract class constructor
multi_index_example( name receiver, name code, datastream<const char*> ds ) :
// contract base class contructor
contract(receiver, code, ds),
// instantiate multi-index instance as data member (find it defined below)
+ datatable(receiver, receiver.value)
{ }
Now you have instantiated a multi-index table, and assigned to datatable
variable, which has a primary index defined for its test_primary
data member.
Here is how the definition of a multi_index_example
contract containing a multi-index table could look like after following all the steps above.
multi_index_example.hpp
#include <inery/inery.hpp>
using namespace inery;
// multi-index example contract class
class [[inery::contract]] multi_index_example : public contract {
public:
using contract::contract;
// contract class constructor
multi_index_example( name receiver, name code, datastream<const char*> ds ) :
// contract base class contructor
contract(receiver, code, ds),
// instantiate multi-index instance as data member (find it defined below)
datatable(receiver, receiver.value)
{ }
// the row structure of the multi-index table, that is, each row of the table
// will contain an instance of this type of structure
struct [[inery::table]] data_structure {
// this data member stores a name for each row of the multi-index table
name test_primary;
// additional data stored in table row
uint64_t datum;
// mandatory definition for primary key getter
uint64_t primary_key( ) const { return test_primary.value; }
};
// the multi-index type definition, for ease of use define a type alias `data_structure_t`,
// based on the multi_index template type, parametarized with a random name and
// the data_structure data structure
typedef inery::multi_index<"datatable"_n, data_structure> data_structure_t;
// the multi-index table instance declared as a data member of type data_structure_t
data_structure_t datatable;
[[inery::action]] void set( name user );
[[inery::action]] void print( name user );
};
Summary
In conclusion, the above instructions show how to define and instantiate a multi-index table instance.