API C++ коннектора
Официальный C++ коннектор для Tarantool расположен в репозитории tarantool/tntcxx.
Он не поставляется в составе репозитория Tarantool и требует дополнительных действий для использования. Сам коннектор представляет собой header-only библиотеку (то есть состоящую только из заголовочных файлов) и не требует установки и сборки. Достаточно клонировать исходный код коннектора и встроить его в свой проект на C++. Подробности и примеры см. в разделе Подключение к Tarantool из C++.
Ниже приведено описание публичного API коннектора.
Класс Connector — это шаблонный класс, который определяет клиент коннектора, который асинхронно обрабатывает множество
соединений с экземплярами Tarantool.
Чтобы создать экземпляр клиента, следует указать реализации буфера и сетевого провайдера в качестве параметров шаблона. Можно реализовать собственный буфер или сетевой провайдер либо использовать встроенные.
Создание экземпляра коннектора по умолчанию выглядит следующим образом:
using Buf_t = tnt::Buffer<16 * 1024>;using Net_t = EpollNetProvider<Buf_t >;Connector<Buf_t, Net_t> client;
int connect(Connection<BUFFER, NetProvider> &conn, const std::string_view& addr, unsigned port, size_t timeout = DEFAULT_CONNECT_TIMEOUT)
Устанавливает соединение с экземпляром Tarantool, который принимает подключения на addr:port. При успешном соединении
метод возвращает 0. Если хост не отвечает в течение времени ожидания или возникает другая ошибка, метод возвращает -1.
В этом случае уточнить причину ошибки можно с помощью метода
Connection.getError().
Параметры:
conn— объект класса Connection.addr— адрес хоста, на котором запущен экземпляр Tarantool.port— порт, на котором экземпляр Tarantool принимает подключения.timeout— время ожидания соединения, секунды. Необязательный. По умолчанию2.
Возвращает
0 при успехе, иначе -1.
Тип возвращаемого значения
int
Возможные ошибки:
- Время ожидания соединения истекло.
- Отказ в соединении (из-за некорректного адреса и/или порта).
- Системные ошибки: не удаётся создать сокет; сбой любого из системных вызовов (
fcntl,select,send,receive).
Пример:
using Buf_t = tnt::Buffer<16 * 1024>;using Net_t = EpollNetProvider<Buf_t >;Connector<Buf_t, Net_t> client;Connection<Buf_t, Net_t> conn(client);int rc = client.connect(conn, "127.0.0.1", 3301);
Основной метод, отвечающий за отправку запроса и проверку готовности ответа.
Запрос следует подготовить заранее с помощью нужного метода класса Connection, например ping() и других, который кодирует запрос в формате MessagePack и сохраняет его в выходном буфере соединения.
wait() отправляет запрос и опрашивает future на предмет готовности ответа. Как только ответ готов, wait()
возвращает 0. Если по истечении timeout ответ не готов или возникает другая ошибка, метод возвращает -1.
В этом случае уточнить причину ошибки можно с помощью метода
Connection.getError().
timeout = 0 означает, что метод опрашивает future до тех пор, пока ответ не будет готов.
Параметры:
conn— объект класса Connection.future— идентификатор запроса, возвращённый методом запроса класса Connection, например ping() и другими.timeout— время ожидания, миллисекунды. Необязательный. По умолчанию0.
Возвращает
0 при получении ответа, иначе -1.
Тип возвращаемого значения
int
Возможные ошибки:
- Превышено время ожидания.
- Другие возможные ошибки зависят от используемого сетевого провайдера. При использовании
EpollNetProviderсбой системных вызововpoll,readиwriteприводит к системным ошибкам, таким какEBADF,ENOTSOCK,EFAULT,EINVAL,EPIPEиENOTCONN(ошибкиEWOULDBLOCKиEAGAINв этом случае не возникают).
Пример:
client.wait(conn, ping, WAIT_TIMEOUT)
void waitAll(Connection<BUFFER, NetProvider> &conn, rid_t *futures, size_t future_count, int timeout = 0)
Как и wait(), метод отправляет подготовленные запросы и проверяет готовность
ответов, но может отправить и несколько разных запросов, хранящихся в массиве futures. Превышение времени
ожидания приводит к ошибке. Уточнить причину ошибки можно с помощью метода
Connection.getError(). timeout = 0 означает, что метод опрашивает
futures до тех пор, пока все ответы не будут готовы.
Параметры:
conn— объект класса Connection.futures— массив с идентификаторами запросов, возвращёнными методами запросов класса Connection, например ping() и другими.future_count— размер массиваfutures.timeout— время ожидания, миллисекунды. Необязательный. По умолчанию0.
Возвращает
Ничего.
Тип возвращаемого значения
none
Возможные ошибки:
- Превышено время ожидания.
- Другие возможные ошибки зависят от используемого сетевого провайдера. При использовании
EpollNetProviderсбой системных вызововpoll,readиwriteприводит к системным ошибкам, таким какEBADF,ENOTSOCK,EFAULT,EINVAL,EPIPEиENOTCONN(ошибкиEWOULDBLOCKиEAGAINв этом случае не возникают).
Пример:
rid_t futures[2];futures[0] = replace;futures[1] = select;client.waitAll(conn, (rid_t *) &futures, 2);
Отправляет все подготовленные на текущий момент запросы и ожидает готовности любого первого ответа. При готовности ответа
waitAny() возвращает соответствующий объект соединения. Если по истечении timeout ни один ответ не готов или возникает
другая ошибка, метод возвращает nullptr. В этом случае уточнить причину ошибки можно с помощью метода
Connection.getError(). timeout = 0 означает отсутствие ограничения по
времени при ожидании готовности ответа.
Параметры:
timeout— время ожидания, миллисекунды. Необязательный. По умолчанию0.
Возвращает
Объект класса Connection при успехе или nullptr при ошибке.
Тип возвращаемого значения
Connection<BUFFER, NetProvider>*
Возможные ошибки:
- Превышено время ожидания.
- Другие возможные ошибки зависят от используемого сетевого провайдера. При использовании
EpollNetProviderсбой системных вызововpoll,readиwriteприводит к системным ошибкам, таким какEBADF,ENOTSOCK,EFAULT,EINVAL,EPIPEиENOTCONN(ошибкиEWOULDBLOCKиEAGAINв этом случае не возникают).
Пример:
rid_t f1 = conn.ping();rid_t f2 = another_conn.ping();Connection<Buf_t, Net_t> *first = client.waitAny(WAIT_TIMEOUT);if (first == &conn) {assert(conn.futureIsReady(f1));} else {assert(another_conn.futureIsReady(f2));}
Закрывает соединение, установленное ранее методом connect().
Параметры:
conn— объект соединения класса Connection.
Возвращает
Ничего.
Тип возвращаемого значения
none
Возможные ошибки: нет.
Пример:
client.close(conn);
Класс Connection — это шаблонный класс, который определяет объекты соединения, необходимые для взаимодействия с
экземпляром Tarantool. Каждый объект соединения привязан к одному сокету.
Как и клиент коннектора, объект соединения также принимает буфер и сетевой провайдер в качестве параметров шаблона, и они должны совпадать с параметрами клиента. Например:
// создание клиента коннектораusing Buf_t = tnt::Buffer<16 * 1024>;using Net_t = EpollNetProvider<Buf_t >;Connector<Buf_t, Net_t> client;// создание объектов соединенияConnection<Buf_t, Net_t> conn01(client);Connection<Buf_t, Net_t> conn02(client);
Класс Connection имеет два вложенных класса — Space и
Index, — которые реализуют методы работы с данными, такие как select(),
replace() и другие.
Псевдоним встроенного типа size_t. rid_t используется для сущностей, которые возвращают или содержат идентификатор
запроса.
Выполняет вызов удалённой хранимой процедуры аналогично вызову conn:call(). Метод возвращает идентификатор запроса, который используется для получения ответа методом getResponse().
Параметры:
func— имя удалённой хранимой процедуры.args— аргументы процедуры.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
На экземпляре Tarantool, к которому выполнено подключение, определена следующая функция:
box.execute("DROP TABLE IF EXISTS t;")box.execute("CREATE TABLE t(id INT PRIMARY KEY, a TEXT, b DOUBLE);")function remote_replace(arg1, arg2, arg3)return box.space.T:replace({arg1, arg2, arg3})end
Вызов функции может выглядеть следующим образом:
rid_t f1 = conn.call("remote_replace", std::make_tuple(5, "some_string", 5.55));
Проверяет доступность идентификатора запроса (future), возвращённого любым из методов запросов, например
ping() и другими.
futureIsReady() возвращает true, если future доступен, и false в противном случае.
Параметры:
future— идентификатор запроса.
Возвращает
true или false.
Тип возвращаемого значения
bool
Возможные ошибки: нет.
Пример:
rid_t ping = conn.ping();conn.futureIsReady(ping);
Метод принимает идентификатор запроса (future) в качестве аргумента и возвращает опциональный объект, содержащий ответ.
Если ответ не готов, метод возвращает std::nullopt. Обратите внимание, что для каждого future метод можно вызвать
только один раз, так как он удаляет идентификатор запроса из внутренней карты сразу после того, как ответ возвращён
пользователю.
Ответ состоит из заголовка (response.header) и тела (response.body). В зависимости от успешности выполнения запроса
на стороне сервера тело может содержать либо ошибки времени выполнения, доступные через response.body.error_stack,
либо данные (кортежи), доступные через response.body.data. Данные являются вектором кортежей. При этом кортежи не
декодированы и приходят в виде указателей на начало и конец MessagePack-данных. Подробнее о декодировании полученных
данных см. раздел Декодирование и чтение данных.
Параметры:
future— идентификатор запроса.
Возвращает
Объект ответа или std::nullopt.
Тип возвращаемого значения
std::optional<Response<BUFFER>>
Возможные ошибки: нет.
Пример:
rid_t ping = conn.ping();std::optional<Response<Buf_t>> response = conn.getResponse(ping);
Возвращает сообщение об ошибке для последней ошибки, произошедшей при выполнении методов классов Connector и Connection.
Возвращает
Сообщение об ошибке.
Тип возвращаемого значения
std::string&
Возможные ошибки: нет.
Пример:
int rc = client.connect(conn, address, port);if (rc != 0) {std::cerr << conn.getError() << std::endl;return -1;}
Сбрасывает соединение после ошибок, то есть очищает сообщение об ошибке и статус соединения.
Возвращает
Ничего.
Тип возвращаемого значения
none
Возможные ошибки: нет.
Пример:
if (client.wait(conn, ping, WAIT_TIMEOUT) != 0) {assert(conn.status.is_failed);std::cerr << conn.getError() << std::endl;conn.reset();}
Подготавливает запрос ping к экземпляру Tarantool.
Метод кодирует запрос в формате MessagePack и помещает его в очередь выходного буфера соединения для последующей отправки одним из методов коннектора, а именно wait(), waitAll() или waitAny().
Возвращает идентификатор запроса, который используется для получения ответа методом getResponse().
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
rid_t ping = conn.ping();
Space — вложенный класс класса Connection. Это публичная обёртка для доступа к
методам работы с данными способом, аналогичным подмодулю Tarantool
box.space, например space[space_id].select(),
space[space_id].replace() и так далее.
Все перечисленные ниже методы класса Space работают следующим образом:
- Метод кодирует соответствующий запрос в формате MessagePack и помещает его в очередь выходного буфера соединения для последующей отправки одним из методов коннектора, а именно wait(), waitAll() или waitAny().
- Метод возвращает идентификатор запроса. Чтобы получить и прочитать сами запрошенные данные, сначала нужно получить объект ответа с помощью метода getResponse(), а затем декодировать данные.
Публичные методы:
template <class T> rid_t select(const T& key, uint32_t index_id = 0, uint32_t limit = UINT32_MAX, uint32_t offset = 0, IteratorType iterator = EQ)
Ищет кортеж или набор кортежей в указанном спейсе. Метод работает аналогично функции
space_object:select() и по умолчанию выполняет
поиск по первичному индексу (index_id = 0). Иначе говоря, space[space_id].select() эквивалентно
space[space_id].index[0].select().
Параметры:
key— значение для сопоставления с ключом индекса.index_id— идентификатор индекса. Необязательный. По умолчанию0.limit— максимальное количество выбираемых кортежей. Необязательный. По умолчаниюUINT32_MAX.offset— количество пропускаемых кортежей. Необязательный. По умолчанию0.iterator— тип итератора. Необязательный. По умолчаниюEQ.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно space_object:select({key_value}, {limit = 1}) в Tarantool */uint32_t space_id = 512;int key_value = 5;uint32_t limit = 1;auto i = conn.space[space_id];rid_t select = i.select(std::make_tuple(key_value), index_id, limit, offset, iter);
Вставляет кортеж в указанный спейс. Если кортеж с таким же первичным ключом уже существует, replace() заменяет
существующий кортеж новым. Метод работает аналогично функции
space_object:replace().
Параметры:
tuple— кортеж для вставки.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно space_object:replace(key_value, "111", 1.01) в Tarantool */uint32_t space_id = 512;int key_value = 5;std::tuple data = std::make_tuple(key_value, "111", 1.01);rid_t replace = conn.space[space_id].replace(data);
Вставляет кортеж в указанный спейс. Метод работает аналогично функции space_object:insert().
Параметры:
tuple— кортеж для вставки.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно space_object:insert(key_value, "112", 2.22) в Tarantool */uint32_t space_id = 512;int key_value = 6;std::tuple data = std::make_tuple(key_value, "112", 2.22);rid_t insert = conn.space[space_id].insert(data);
Обновляет кортеж в указанном спейсе. Метод работает аналогично функции
space_object:update() и по умолчанию ищет
обновляемый кортеж по первичному индексу (index_id = 0). Иначе говоря, space[space_id].update() эквивалентно
space[space_id].index[0].update().
Параметр tuple задаёт операцию обновления, идентификатор обновляемого поля и новое значение поля. Набор доступных
операций и формат указания операции и идентификатора поля такие же, как в Tarantool. Подробности см. в описании
функции space_object:update() и в примере ниже.
Параметры:
key— значение для сопоставления с ключом индекса.tuple— параметры операции обновления, а именноoperator, field_identifier, value.index_id— идентификатор индекса. Необязательный. По умолчанию0.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно space_object:update(key, {{'=', 1, 'update' }, {'+', 2, 12}}) в Tarantool */uint32_t space_id = 512;std::tuple key = std::make_tuple(5);std::tuple op1 = std::make_tuple("=", 1, "update");std::tuple op2 = std::make_tuple("+", 2, 12);rid_t f1 = conn.space[space_id].update(key, std::make_tuple(op1, op2));
Обновляет или вставляет кортеж в указанный спейс. Метод работает аналогично функции space_object:upsert().
Если существует кортеж, совпадающий с ключевыми полями tuple, запрос действует так же, как
update(), и используется параметр ops. Если кортежа, совпадающего с
ключевыми полями tuple, нет, запрос действует так же, как insert()
и используется параметр tuple.
Параметры:
tuple— кортеж для вставки.ops— параметры операции обновления, а именноoperator, field_identifier, value.index_base— начальный номер для нумерации полей в кортеже:0или1. Необязательный. По умолчанию0.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно space_object:upsert({333, "upsert-insert", 0.0}, {{'=', 1, 'upsert-update'}}) в Tarantool */uint32_t space_id = 512;std::tuple tuple = std::make_tuple(333, "upsert-insert", 0.0);std::tuple op1 = std::make_tuple("=", 1, "upsert-update");rid_t f1 = conn.space[space_id].upsert(tuple, std::make_tuple(op1));
Удаляет кортеж в указанном спейсе. Метод работает аналогично функции
space_object:delete() и по умолчанию ищет
удаляемый кортеж по первичному индексу (index_id = 0). Иначе говоря, space[space_id].delete_() эквивалентно
space[space_id].index[0].delete_().
Параметры:
key— значение для сопоставления с ключом индекса.index_id— идентификатор индекса. Необязательный. По умолчанию0.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно space_object:delete(123) в Tarantool */uint32_t space_id = 512;std::tuple key = std::make_tuple(123);rid_t f1 = conn.space[space_id].delete_(key);
Index — вложенный класс класса Space. Это публичная обёртка для доступа
к методам работы с данными способом, аналогичным подмодулю Tarantool
box.index, например
space[space_id].index[index_id].select() и так далее.
Все перечисленные ниже методы класса Index работают следующим образом:
- Метод кодирует соответствующий запрос в формате MessagePack и помещает его в очередь выходного буфера соединения для последующей отправки одним из методов коннектора, а именно wait(), waitAll() или waitAny().
- Метод возвращает идентификатор запроса, который используется для получения ответа методом getResponse(). Чтобы разобраться в структуре ответа и способе чтения запрошенных данных, см. описание getResponse().
Публичные методы:
template <class T> rid_t select(const T &key, uint32_t limit = UINT32_MAX, uint32_t offset = 0, IteratorType iterator = EQ)
Альтернатива методу space.select(). Метод ищет кортеж или набор кортежей в указанном спейсе по конкретному индексу и работает аналогично функции index_object:select().
Параметры:
key— значение для сопоставления с ключом индекса.limit— максимальное количество выбираемых кортежей. Необязательный. По умолчаниюUINT32_MAX.offset— количество пропускаемых кортежей. Необязательный. По умолчанию0.iterator— тип итератора. Необязательный. По умолчаниюEQ.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно index_object:select({key}, {limit = 1}) в Tarantool */uint32_t space_id = 512;uint32_t index_id = 1;int key = 10;uint32_t limit = 1;auto i = conn.space[space_id].index[index_id];rid_t select = i.select(std::make_tuple(key), limit, offset, iter);
Альтернатива методу space.update(). Метод обновляет кортеж в указанном спейсе, но ищет кортеж по конкретному индексу. Метод работает аналогично функции index_object:update().
Параметр tuple задаёт операцию обновления, идентификатор обновляемого поля и новое значение поля. Набор доступных
операций и формат указания операции и идентификатора поля такие же, как в Tarantool. Подробности см. в описании
функции index_object:update() и в примере ниже.
Параметры:
key— значение для сопоставления с ключом индекса.tuple— параметры операции обновления, а именноoperator, field_identifier, value.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно index_object:update(key, {{'=', 1, 'update' }, {'+', 2, 12}}) в Tarantool */uint32_t space_id = 512;uint32_t index_id = 1;std::tuple key = std::make_tuple(10);std::tuple op1 = std::make_tuple("=", 1, "update");std::tuple op2 = std::make_tuple("+", 2, 12);rid_t f1 = conn.space[space_id].index[index_id].update(key, std::make_tuple(op1, op2));
Альтернатива методу space.delete_(). Метод удаляет кортеж в указанном спейсе, но ищет кортеж по конкретному индексу. Метод работает аналогично функции index_object:delete().
Параметры:
key— значение для сопоставления с ключом индекса.
Возвращает
Идентификатор запроса.
Тип возвращаемого значения
rid_t
Возможные ошибки: нет.
Пример:
/* Эквивалентно index_object:delete(123) в Tarantool */uint32_t space_id = 512;uint32_t index_id = 1;std::tuple key = std::make_tuple(123);rid_t f1 = conn.space[space_id].index[index_id].delete_(key);