Коннекторы
Коннекторы – это API, с помощью которых можно использовать Tarantool с различными языками программирования.
Коннекторы можно разделить на две группы – поддерживаемые командой Tarantool и поддерживаемые сообществом. Команда Tarantool поддерживает следующие коннекторы:
Все остальные коннекторы поддерживаются сообществом, что означает, что поддержка новых возможностей Tarantool может быть отложена. Все доступные коннекторы перечислены на странице Коннекторы.
Бинарный протокол Tarantool разработан с акцентом на асинхронный ввод-вывод и простую интеграцию с прокси. Каждый клиентский запрос начинается с заголовка переменной длины, содержащего идентификатор запроса, тип запроса, идентификатор экземпляра, номер последовательности журнала и т.д.
Обязательное поле длины в заголовке запроса упрощает ввод-вывод на стороне клиента или прокси. Ответ на запрос отправляется клиенту сразу после готовности. В заголовке ответа всегда присутствуют тот же тип и идентификатор, что и в запросе. Идентификатор позволяет сопоставить запрос с ответом, даже если ответы приходят не по порядку.
Если вы не реализуете клиентский драйвер, вам не нужно вникать в детали бинарного протокола. Драйверы для конкретных языков предоставляют удобный способ хранения структур данных предметной области в Tarantool. Полное описание бинарного протокола поддерживается в аннотированной форме Бэкуса-Наура в дереве исходного кода. Подробные примеры и диаграммы всех запросов и ответов бинарного протокола см. в разделе Бинарный протокол.
API Tarantool предназначен для того, чтобы клиентская программа могла отправить пакет запроса серверному экземпляру и получить
ответ. Ниже приведён пример того, что клиент отправляет для box.space[513]:insert{'A', 'BB'}. Описание компонентов в формате
BNF приведено на странице Бинарный протокол.
Компонент | Байт #0 | Байт #1 | Байт #2 | Байт #3 |
|---|---|---|---|---|
код insert | 02 | |||
остаток заголовка | ... | ... | ... | ... |
2-значное число: id спейса | cd | 02 | 01 | |
код кортежа | 21 | |||
1-значное число: полей = 2 | 92 | |||
строка (1 символ): field[1] | a1 | 41 | ||
строка (2 символа): field[2] | a2 | 42 | 42 |
Теперь можно отправить этот пакет экземпляру Tarantool и интерпретировать ответ (на странице
Бинарный протокол приведено описание формата пакетов как
для запросов, так и для ответов). Однако было бы проще и менее ошибочно вызывать подпрограмму, которая форматирует пакет в
соответствии с типизированными параметрами. Например, response = tarantool_routine("insert", 513, "A", "B");. Именно для
этого существуют API драйверов для Perl, Python, PHP и т.д.
В этом разделе приведены примеры подключения к экземпляру Tarantool с помощью коннекторов для Perl, PHP, Python, node.js и C. В примерах используются жёстко заданные параметры, и они будут работать только при соблюдении следующих условий:
- Экземпляр Tarantool (tarantool) запущен на
localhost(127.0.0.1) и принимает подключения на порту 3301 (box.cfg.listen = '3301'); - Спейс
examplesимеет id = 999 (box.space.examples.id = 999) и первичный индекс по числовому полю (box.space[999].index[0].parts[1].type = "unsigned"); - Пользователь
guestимеет права на чтение и запись.
Выполнить все эти условия можно, запустив экземпляр и выполнив следующий скрипт:
box.cfg{listen=3301}box.schema.space.create('examples',{id=999})box.space.examples:create_index('primary', {type = 'hash', parts = {1, 'unsigned'}})box.schema.user.grant('guest','read,write','space','examples')box.schema.user.grant('guest','read','space','_space')
При вызове функции через Tarantool с использованием любого коннектора возвращаемое значение представлено в формате MsgPack. Если функция вызывается через API коннектора, могут выполняться некоторые преобразования. Все скалярные значения возвращаются в виде кортежей (с идентификатором типа MsgPack, за которым следует значение); все нескалярные значения возвращаются в виде группы кортежей (с идентификатором массива MsgPack, за которым следуют скалярные значения). Если функция вызывается через командный слой бинарного протокола – «eval» – а не через API коннектора, преобразования не выполняются.
В следующем примере создаётся Lua-функция. Поскольку к ней будет внешний доступ от имени
пользователя guest, потребуется
LINK_NOT_DEFINED(../reference/reference_lua/box/box_schema/user_grant) привилегии на выполнение.
Функция возвращает пустой массив, скалярную строку, два логических значения и короткое целое число. Значения соответствуют
описанным в таблице
Стандартные типы и кодировки MsgPack.
tarantool> box.cfg{listen=3301}2016-03-03 18:45:52.802 [27381] main/101/interactive I> ready to accept requests---...tarantool> function f() return {},'a',false,true,127; end---...tarantool> box.schema.func.create('f')---...tarantool> box.schema.user.grant('guest','execute','function','f')---...
Ниже приведена программа на C, вызывающая эту функцию. Хотя в примере используется C, результат будет точно таким же, если вызывающая программа написана на Perl, PHP, Python, Go или Java.
#include <stdio.h>#include <stdlib.h>#include <tarantool/tarantool.h>#include <tarantool/tnt_net.h>#include <tarantool/tnt_opt.h>void main() {struct tnt_stream *tnt = tnt_net(NULL); /* НАСТРОЙКА */tnt_set(tnt, TNT_OPT_URI, "localhost:3301");if (tnt_connect(tnt) < 0) { /* ПОДКЛЮЧЕНИЕ */printf("Connection refused\n");exit(-1);}struct tnt_stream *arg; arg = tnt_object(NULL); /* ФОРМИРОВАНИЕ ЗАПРОСА */tnt_object_add_array(arg, 0);struct tnt_request *req1 = tnt_request_call(NULL); /* ВЫЗОВ функции f() */tnt_request_set_funcz(req1, "f");uint64_t sync1 = tnt_request_compile(tnt, req1);tnt_flush(tnt); /* ОТПРАВКА ЗАПРОСА */struct tnt_reply reply; tnt_reply_init(&reply); /* ПОЛУЧЕНИЕ ОТВЕТА */tnt->read_reply(tnt, &reply);if (reply.code != 0) {printf("Call failed %lu.\n", reply.code);exit(-1);}const unsigned char *p= (unsigned char*)reply.data; /* ВЫВОД ОТВЕТА */while (p < (unsigned char *) reply.data_end){printf("%x ", *p);++p;}printf("\n");tnt_close(tnt); /* ЗАВЕРШЕНИЕ */tnt_stream_free(arg);tnt_stream_free(tnt);}
При выполнении этой программы будет выведено:
dd 0 0 0 5 90 91 a1 61 91 c2 91 c3 91 7f
Первые пять байтов – dd 0 0 0 5 – это кодировка MsgPack для «32-битного заголовка массива со значением 5» (см. спецификацию
MsgPack). Остальные байты соответствуют описанию в таблице
Стандартные типы и кодировки MsgPack.