6 Вторичные индексы
В этом разделе приведено описание сортировки таблиц по индексам на примере таблицы voteinfo
, а также инструкции по добавлению индекса в таблицу на примере контракта addressbook
.
Формат таблицы и индексов
В EOS для каждого индекса создается структура, которая возвращает значение. В CyberWay для описания индекса либо создается отдельная функция и при этом используется const_mem_fun
в описании таблицы, либо используется поле из структуры eosio::member
.
Требование к формату таблицы
Описание таблицы должно соответствовать следующему формату:
Параметры:
N(vote)
— первичный индекс;
vote_table
— имя таблицы;
voteinfo
— имя структуры;
vote_id_index
— индекс первичного ключа (primary key
);
vote_messageid_index
— индекс, идентифицирующий сообщение. Для каждого голоса при голосовании формируется сообщение, которому присваивается номер. По этому номеру в таблице отыскивается сообщение;
vote_group_index
— вторичный индекс, составной.
В таблице всегда должны быть:
первичный индекс (тип
uint64
);определенное количество вторичных индексов, которые могут быть описаны как по одному полю с использованием
by_message
, так и по нескольким полям.
Описание вторичного индекса по одному полю имеет вид:
При описании вторичного индекса по нескольким полям указываются следующие параметры:
шаблон индекса
by_
;имя индекса;
описание индекса:
const_mem_fun
— описание в простом виде;eosio::member
— описание в сложном виде.
При описании вторичного индекса в сложном виде eosio::member
указываются composite_key
, имя структуры и перечень полей, из которых формируется индекс (например, из полей message_id
и voter
).
Требование к описанию вторичных индексов
Описание вторичных индексов должно совпадать с их описанием в ABI-файле. При этом должен быть соблюден порядок расположения, а также соответствие типов. Сериализация и десериализация передаваемых данных в бинарном виде должны выполняться одинаковым способом.
В зависимости от назначения вторичных индексов существуют два способа их описания:
описание для работы внутри контракта;
описание для работы вне контракта. При этом описание таблицы с индексами находится в ABI-файле.
Описание вторичного индекса для работы внутри контракта
Описание полей name
и info
аналогично описанию в EOS. Отличие от EOS состоит в том, что вместо полей индексов indexed_name
и indexed_type
, используемых в EOS, в CyberWay используются описание индексов.
Индекс представляет собой массив, в котором каждому индексу присваивается имя. Это имя должно совпадать с именем, указанным в шаблоне indexed_by
. Совпадение идет по следующим признакам:
N(id)
— совпадение по порядковому номеру параметра. Например, N1 — выбор первичного индекса;N(messageid)
— совпадение по порядковому номеру сообщения. Каждому голосу во время голосования присваивается номер сообщения;N(byvoter)
— совпадение по порядковому номеру голосуемого.
Описание вторичного индекса для работы вне контракта
В описание индекса введено понятие уникальности «unique» — будет ли значение этого индекса для записи уникальным или нет. Значение unique=true
означает уникальность.
Сортировка обеспечивает упорядоченное расположение индексов.
В поле «orders» указываются все поля, которые будут отсортированы. Описание таблицы для смарт-контракта указывается в ABI-файле. Есть порядок, в котором описываются поля индексов (messageid
и voter
). Значения этих полей должны следовать в том порядке, в котором они содержатся в composite_key
, а именно в eosio::member
или const_mem_ func
. Второй атрибут order
определяет способ построения индекса внутри базы данных. Этот параметр определяет порядок появления элементов, если эти элементы извлекаются из таблицы один за другим, то есть определяет правило, по которому находится очередной элемент в таблице.
Пример описания таблицы с индексами в ABI-файле:
Пример использования индексов внутри смарт-контракта
Вторичный индекс используется из одного поля, то есть messageid
состоит из одного поля.
lower_bound
— используется для поиска нижней границы по указанному ID. От найденной нижней границы индекс проходит по всем голосам, пока голос считается отданным за тот же самый пост.
Пример использования составного вторичного индекса
byvoter
— состоит из двух полей, передаваемых через make_tuple
. Используется для поиска голоса, относящегося к сообщению mssg_itr->id
проголосовавшего пользователя voter
.
Пример добавления индекса в таблицу контракта addressbook
В предыдущем разделе рассмотрены инструкции по созданию и настройке таблицы addressbook
. Далее приводятся инструкции по добавлению индекса в данную тавлицу.
6.1 Удалить существующие записи из таблицы
Структура таблицы не может быть изменена, если она содержит данные. Необходимо удалить уже имеющиеся в ней записи пользователей alice
и bob
.
6.2 Добавить новое поле для индекса к контракту addressbook.cpp Поскольку вторичный индекс должен быть числовым полем, добавляется переменная типа uint64_t.
6.3 Добавить вторичный индекс для таблицы addresses
Поле определено как вторичный индекс. Необходимо переконфигурировать таблицу address_index
.
index_by
— структура, которая используется для создания экземпляра индекса. «byage»
— оператор вызова функции, который извлекает значение const в качестве ключа индекса.
Таблица с несколькими индексами будет индексировать записи по переменной age
.
6.4 Обновить параметры функции upsert С учетом всех изменений функция будет иметь вид:
Добавить дополнительные строки для обновления поля age
в функции upsert
следующим образом:
6.5 Скомпилировать и развернуть контракт addressbook
6.6 Описать индексы в ABI-файле, после чего исполнить:
6.7 Тестирование
Вставить записи в таблицу пользователей alice
и bob
.
Проверить данные таблицы для пользователей alice
и bob
по индексу age
. В командных строках использовать параметр --index 2
для указания запроса по вторичному индексу (индекс № 2).
Поиск данных таблицы по вторичному индексу считается успешно выполненным, если будет получена информация вида:
Last updated