С
tarantool-c – официальный коннектор для Tarantool на языке C. См. полную документацию по библиотеке коннектора.
Ниже приведены два примера использования высокоуровневого C API Tarantool.
Ниже приведена полная программа на C, которая вставляет кортеж [99999,'B'] в спейс examples при помощи
высокоуровневого C API.
#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 *tuple = tnt_object(NULL); /* см. ниже в разделе = ФОРМИРОВАНИЕ ЗАПРОСА */tnt_object_format(tuple, "[%d%s]", 99999, "B");tnt_insert(tnt, 999, tuple); /* см. ниже в разделе = ОТПРАВКА ЗАПРОСА */tnt_flush(tnt);struct tnt_reply reply; tnt_reply_init(&reply); /* см. ниже в разделе = ПОЛУЧЕНИЕ ОТВЕТА */tnt->read_reply(tnt, &reply);if (reply.code != 0) {printf("Insert failed %lu.\n", reply.code);}tnt_close(tnt); /* см. ниже в разделе = ЗАВЕРШЕНИЕ */tnt_stream_free(tuple);tnt_stream_free(tnt);}
Поместите код в файл с именем example.c и установите библиотеку tarantool-c. Один из способов установки
библиотеки tarantool-c (на Ubuntu):
$ git clone git://github.com/tarantool/tarantool-c.git ~/tarantool-c$ cd ~/tarantool-c$ git submodule init$ git submodule update$ cmake .$ make$ make install
Для компиляции и компоновки программы выполните:
$ # иногда это необходимо:$ export LD_LIBRARY_PATH=/usr/local/lib$ gcc -o example example.c -ltarantool
Перед запуском убедитесь, что экземпляр сервера принимает подключения на адресе localhost:3301 и что спейс examples
существует, как описано в разделе Настройка сервера для примеров с коннекторами. Для запуска программы выполните
команду ./example. Программа подключится к экземпляру Tarantool и отправит запрос. Если Tarantool не запущен на имени
хоста localhost с портом 3301 для приёма подключений, программа выведет сообщение Connection refused. Если
вставка завершится неудачей, программа выведет сообщение Insert failed с номером ошибки (полный список кодов ошибок
см. в исходном файле /src/box/errcode.h).
Ниже приведены пояснения к комментариям в программе из примера.
Настройка начинается с создания потока.
struct tnt_stream *tnt = tnt_net(NULL);tnt_set(tnt, TNT_OPT_URI, "localhost:3301");
В этой программе поток будет назван tnt. Перед подключением через поток tnt может потребоваться задать некоторые
параметры. Наиболее важный параметр – TNT_OPT_URI. В данной программе
URI – localhost:3301, так как именно там
экземпляр Tarantool должен принимать подключения.
Описание функции:
struct tnt_stream *tnt_net(struct tnt_stream *s)int tnt_set(struct tnt_stream *s, int option, variant option-value)
Теперь, когда поток с именем tnt создан и связан с URI, программа может подключиться к экземпляру сервера.
if (tnt_connect(tnt) < 0){ printf("Connection refused\n"); exit(-1); }
Описание функции:
int tnt_connect(struct tnt_stream *s)
Подключение может завершиться неудачей по разным причинам, например: сервер не запущен или URI содержит неверный пароль. При неудачном подключении возвращаемое значение будет равно -1.
Для большинства запросов требуется передать структурированное значение, например, содержимое кортежа.
struct tnt_stream *tuple = tnt_object(NULL);tnt_object_format(tuple, "[%d%s]", 99999, "B");
В этой программе запросом будет INSERT,
а содержимым кортежа – целое число и строка. Это простой последовательный набор значений, то есть без вложенных структур
или массивов. Поэтому в данном случае отформатировать передаваемые данные легко, используя те же типы аргументов, что и
в C-функции printf(): %d для целого числа, %s для строки, затем целочисленное значение, затем указатель на
строковое значение.
Описание функции:
ssize_t tnt_object_format(struct tnt_stream *s, const char *fmt, ...)
Запросы для работы с базой данных аналогичны запросам из библиотеки box.
tnt_insert(tnt, 999, tuple);tnt_flush(tnt);
В этой программе выполняется запрос INSERT, поэтому программа передаёт tnt_stream, использованный для подключения
(tnt), и tnt_stream, подготовленный с помощью tarantoolc:tnt_object_format (tuple).
Описание функции:
ssize_t tnt_insert(struct tnt_stream *s, uint32_t space, struct tnt_stream *tuple)ssize_t tnt_replace(struct tnt_stream *s, uint32_t space, struct tnt_stream *tuple)ssize_t tnt_select(struct tnt_stream *s, uint32_t space, uint32_t index,uint32_t limit, uint32_t offset, uint8_t iterator,struct tnt_stream *key)ssize_t tnt_update(struct tnt_stream *s, uint32_t space, uint32_t index,struct tnt_stream *key, struct tnt_stream *ops)
В ответ на большинство запросов клиент получает ответ, содержащий признак успешности выполнения и набор кортежей.
struct tnt_reply reply; tnt_reply_init(&reply);tnt->read_reply(tnt, &reply);if (reply.code != 0){ printf("Insert failed %lu.\n", reply.code); }
Программа проверяет успешность выполнения, но не декодирует остальную часть ответа.
Описание функции:
struct tnt_reply *tnt_reply_init(struct tnt_reply *r)tnt->read_reply(struct tnt_stream *s, struct tnt_reply *r)void tnt_reply_free(struct tnt_reply *r)
При завершении сеанса следует закрыть подключение, установленное с помощью tarantoolc:tnt_connect, и уничтожить
объекты, созданные на этапе настройки.
tnt_close(tnt);tnt_stream_free(tuple);tnt_stream_free(tnt);
Описание функции:
void tnt_close(struct tnt_stream *s)void tnt_stream_free(struct tnt_stream *s)
Ниже приведена полная программа на C, которая выполняет выборку по ключу индекса [99999] из спейса examples
через высокоуровневый C API. Для вывода результатов программа использует функции из библиотеки
MsgPuck, с помощью которых можно декодировать массивы в формате
MessagePack.
#include <stdio.h>#include <stdlib.h>#include <tarantool/tarantool.h>#include <tarantool/tnt_net.h>#include <tarantool/tnt_opt.h>#define MP_SOURCE 1#include <msgpuck.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 *tuple = tnt_object(NULL);tnt_object_format(tuple, "[%d]", 99999); /* кортеж = ключ поиска */tnt_select(tnt, 999, 0, UINT32_MAX, 0, 0, tuple);tnt_flush(tnt);struct tnt_reply reply; tnt_reply_init(&reply);tnt->read_reply(tnt, &reply);if (reply.code != 0) {printf("Select failed.\n");exit(1);}char field_type;field_type = mp_typeof(*reply.data);if (field_type != MP_ARRAY) {printf("no tuple array\n");exit(1);}long unsigned int row_count;uint32_t tuple_count = mp_decode_array(&reply.data);printf("tuple count=%u\n", tuple_count);unsigned int i, j;for (i = 0; i < tuple_count; ++i) {field_type = mp_typeof(*reply.data);if (field_type != MP_ARRAY) {printf("no field array\n");exit(1);}uint32_t field_count = mp_decode_array(&reply.data);printf(" field count=%u\n", field_count);for (j = 0; j < field_count; ++j) {field_type = mp_typeof(*reply.data);if (field_type == MP_UINT) {uint64_t num_value = mp_decode_uint(&reply.data);printf(" value=%lu.\n", num_value);} else if (field_type == MP_STR) {const char *str_value;uint32_t str_value_length;str_value = mp_decode_str(&reply.data, &str_value_length);printf(" value=%.*s.\n", str_value_length, str_value);} else {printf("wrong field type\n");exit(1);}}}tnt_close(tnt);tnt_stream_free(tuple);tnt_stream_free(tnt);}
Как и в первом примере, поместите код в файл с именем example2.c.
Для компиляции и компоновки программы выполните:
$ gcc -o example2 example2.c -ltarantool
Для запуска программы выполните ./example2.
Два примера программ демонстрируют лишь некоторые запросы и не охватывают все аспекты, необходимые для полноценной работы. Подробнее см. в документации tarantool-c на GitHub.