Skip to main content

Instantiate Composition

This instructions provides details about how to instantiate a indexed composition i Inery Value Contract. Complete the following steps to instantiate a indexed composition container.

Value Contract SetUp

If you don't have Value Contract Set up, Go back to Create Constructor

Define The Composition Data Structure

Define the data structure for the indexed composition.

Define Composition structure
  struct [[inery::table]] data_structure {
};
Use Macro

You can wrap struct definition with TABLE macro deinfed in inery-cpp compiler.

TABLE data_structure{};
Define Composition Records
  TABLE data_structure {

// we will use this record as primary index
name owner;

// additional record stored in composition
uint64_t data;
};

Define The Primary Index

Add the definition of the primary index for the indexed composition. 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 record to use as the primary key.

Primary Index

Each data member corresponds to a record of the indexed composition. A primary key is required when defining a indexed composition structure, therefore you need to know which record will be the primary key for your indexed composition. The corresponding data member for the primary key record must store unique values.

Add Getter by Primary Index
  TABLE data_structure {
name owner;
uint64_t data;

// mandatory definition for primary key getter
uint64_t primary_key( ) const { return owner.value; }
};
tip

Other, secondary, indexes if they will be defined can have duplicates.
You can have up to 16 additional indexes and the record types can be uint64_t, uint128_t, uint256_t, double or long double.

Define A Multi-Index Type Alias

Define a type alias data_structure_t based on the inery::multi_index template type, parametarized with a random name container and the data_structure data structure.

note

The names must adhere to inrey::name data type restrictions.

  TABLE data_structure {
name owner;
uint64_t data;
uint64_t primary_key( ) const { return owner.value; }
};
// Add composition typedef
typedef inery::multi_index<"container"_n, data_structure> data_structure_t;

Instantiate The Composition

Declare the container indexed composition as a data member of type data_structure_t.

  // the data structure which defines each row of the table
TABLE data_structure {
// this data member stores a name for each row of the indexed composition
name owner;
// additional data stored in table row
uint64_t data;
// mandatory definition for primary key getter
uint64_t primary_key( ) const { return owner.value; }
};

typedef inery::multi_index<"container"_n, data_structure> data_structure_t;
+ data_structure_t container;

Initialize The indexed composition Instance

Initialize the data member container 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 "container" provide access to the partition of the RAM cache used by this indexed composition, in this example you will initialize the container data member in the value contract constructor

Add Composition to Constructor
// contract class constructor
database( name receiver, name code, datastream<const char*> ds ) :
// contract base class contructor
contract(receiver, code, ds),
// instantiate composition instance as data member (find it defined below)
+ container(receiver, receiver.value)
{ }

Now you have instantiated a indexed composition, and assigned to container variable, which has a primary index defined for its owner data member.

Here is how the definition of a database contract containing a indexed composition could look like after following all the steps above.

Complete Hpp File
#include <inery/inery.hpp>
using namespace inery;

// multi-index example contract class
class [[inery::contract]] database : public contract {
public:
using contract::contract;

// contract class constructor
database( 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)
container(receiver, receiver.value)
{ }

// the row structure of the indexed composition, that is, each row of the table
// will contain an instance of this type of structure
TABLE data_structure {
// this data member stores a name for each row of the indexed composition
name owner;
// additional data stored in table row
uint64_t data;
// mandatory definition for primary key getter
uint64_t primary_key( ) const { return owner.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<"container"_n, data_structure> data_structure_t;

// the indexed composition instance declared as a data member of type data_structure_t
data_structure_t container;

[[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 indexed composition instance.