C++ connector API
The official C++ connector for Tarantool is located in the tanartool/tntcxx repository.
It is not supplied as part of the Tarantool repository and requires additional actions for usage. The connector itself is a header-only library and, as such, doesn’t require installation and building. All you need is to clone the connector source code and embed it in your C++ project. See the C++ connector Getting started document for details and examples.
Below is the description of the connector public API.
-
template<class
BUFFER
, classNetProvider
= EpollNetProvider<BUFFER>>
classConnector
¶ The
Connector
class is a template class that defines a connector client which can handle many connections to Tarantool instances asynchronously.To instantiate a client, you should specify the buffer and the network provider implementations as template parameters. You can either implement your own buffer or network provider or use the default ones.
The default connector instantiation looks as follows:
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)¶ Connects to a Tarantool instance that is listening on
addr:port
. On successful connection, the method returns0
. If the host doesn’t reply within the timeout period or another error occurs, it returns-1
. Then, Connection.getError() gives the error message.Parameters: - conn – object of the Connection class.
- addr – address of the host where a Tarantool instance is running.
- port – port that a Tarantool instance is listening on.
- timeout – connection timeout, seconds. Optional. Defaults to
2
.
Returns: 0
on success, or-1
otherwise.Rtype: int
Possible errors:
- connection timeout
- refused to connect (due to incorrect address or/and port)
- system errors: a socket can’t be created; failure of any of the system
calls (
fcntl
,select
,send
,receive
).
Example:
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);
-
int
wait
(Connection<BUFFER, NetProvider> &conn, rid_t future, int timeout = 0)¶ The main method responsible for sending a request and checking the response readiness.
You should prepare a request beforehand by using the necessary method of the Connection class, such as ping() and so on, which encodes the request in the MessagePack format and saves it in the output connection buffer.
wait()
sends the request and is polling thefuture
for the response readiness. Once the response is ready,wait()
returns0
. If attimeout
the response isn’t ready or another error occurs, it returns-1
. Then, Connection.getError() gives the error message.timeout = 0
means the method is polling thefuture
until the response is ready.Parameters: - conn – object of the Connection class.
- future – request ID returned by a request method of the Connection class, such as, ping() and so on.
- timeout – waiting timeout, milliseconds. Optional. Defaults to
0
.
Returns: 0
on receiving a response, or-1
otherwise.Rtype: int
Possible errors:
- timeout exceeded
- other possible errors depend on a network provider used.
If the
EpollNetProvider
is used, failing of thepoll
,read
, andwrite
system calls leads to system errors, such as,EBADF
,ENOTSOCK
,EFAULT
,EINVAL
,EPIPE
, andENOTCONN
(EWOULDBLOCK
andEAGAIN
don’t occur in this case).
Example:
client.wait(conn, ping, WAIT_TIMEOUT)
-
void
waitAll
(Connection<BUFFER, NetProvider> &conn, rid_t *futures, size_t future_count, int timeout = 0)¶ Similar to wait(), the method sends the requests prepared and checks the response readiness, but can send several different requests stored in the
futures
array. Exceeding the timeout leads to an error; Connection.getError() gives the error message.timeout = 0
means the method is polling thefutures
until all the responses are ready.Parameters: - conn – object of the Connection class.
- futures – array with the request IDs returned by request methods of the Connection class, such as, ping() and so on.
- future_count – size of the
futures
array. - timeout – waiting timeout, milliseconds. Optional. Defaults to
0
.
Returns: none
Rtype: none
Possible errors:
- timeout exceeded
- other possible errors depend on a network provider used.
If the
EpollNetProvider
is used, failing of thepoll
,read
, andwrite
system calls leads to system errors, such as,EBADF
,ENOTSOCK
,EFAULT
,EINVAL
,EPIPE
, andENOTCONN
(EWOULDBLOCK
andEAGAIN
don’t occur in this case).
Example:
rid_t futures[2]; futures[0] = replace; futures[1] = select; client.waitAll(conn, (rid_t *) &futures, 2);
-
Connection<BUFFER, NetProvider> *
waitAny
(int timeout = 0)¶ Sends all requests that are prepared at the moment and is waiting for any first response to be ready. Upon the response readiness,
waitAny()
returns the corresponding connection object. If attimeout
no response is ready or another error occurs, it returnsnullptr
. Then, Connection.getError() gives the error message.timeout = 0
means no time limitation while waiting for the response readiness.Parameters: timeout – waiting timeout, milliseconds. Optional. Defaults to 0
.Returns: object of the Connection class on success, or nullptr
on error.Rtype: Connection<BUFFER, NetProvider>* Possible errors:
- timeout exceeded
- other possible errors depend on a network provider used.
If the
EpollNetProvider
is used, failing of thepoll
,read
, andwrite
system calls leads to system errors, such as,EBADF
,ENOTSOCK
,EFAULT
,EINVAL
,EPIPE
, andENOTCONN
(EWOULDBLOCK
andEAGAIN
don’t occur in this case).
Example:
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)); }
-
void
close
(Connection<BUFFER, NetProvider> &conn)¶ Closes the connection established earlier by the connect() method.
Parameters: conn – connection object of the Connection class. Returns: none Rtype: none Possible errors: none.
Example:
client.close(conn);
-
template<class
BUFFER
, classNetProvider
>
classConnection
¶ The
Connection
class is a template class that defines a connection objects which is required to interact with a Tarantool instance. Each connection object is bound to a single socket.Similar to a connector client, a connection object also takes the buffer and the network provider as template parameters, and they must be the same as ones of the client. For example:
//Instantiating a connector client using Buf_t = tnt::Buffer<16 * 1024>; using Net_t = EpollNetProvider<Buf_t >; Connector<Buf_t, Net_t> client; //Instantiating connection objects Connection<Buf_t, Net_t> conn01(client); Connection<Buf_t, Net_t> conn02(client);
The
Connection
class has two nested classes, namely, Space and Index that implement the data-manipulation methods likeselect()
,replace()
, and so on.
-
typedef size_t
rid_t
¶ The alias of the built-in
size_t
type.rid_t
is used for entities that return or contain a request ID.
-
template<class
T
>
rid_tcall
(const std::string &func, const T &args)¶ Executes a call of a remote stored-procedure similar to conn:call(). The method returns the request ID that is used to get the response by getResponse().
Parameters: - func – a remote stored-procedure name.
- args – procedure’s arguments.
Returns: a request ID
Rtype: rid_t
Possible errors: none.
Example:
The following function is defined on the Tarantool instance you are connected to:
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
The function call can look as follows:
rid_t f1 = conn.call("remote_replace", std::make_tuple(5, "some_sring", 5.55));
-
bool
futureIsReady
(rid_t future)¶ Checks availability of a request ID (
future
) returned by any of the request methods, such as, ping() and so on.futureIsReady()
returnstrue
if thefuture
is available orfalse
otherwise.Parameters: future – a request ID. Returns: true
orfalse
Rtype: bool Possible errors: none.
Example:
rid_t ping = conn.ping(); conn.futureIsReady(ping);
-
std::optional<Response<BUFFER>>
getResponse
(rid_t future)¶ The method takes a request ID (
future
) as an argument and returns an optional object containing a response. If the response is not ready, the method returnsstd::nullopt
. Note that for eachfuture
the method can be called only once because it erases the request ID from the internal map as soon as the response is returned to a user.A response consists of a header (
response.header
) and a body (response.body
). Depending on success of the request execution on the server side, body may contain either runtime errors accessible byresponse.body.error_stack
or data (tuples) accessible byresponse.body.data
. Data is a vector of tuples. However, tuples are not decoded and come in the form of pointers to the start and the end of MessagePacks. For details on decoding the data received, refer to “Decoding and reading the data”.Parameters: future – a request ID Returns: a response object or std::nullopt
Rtype: std::optional<Response<BUFFER>> Possible errors: none.
Example:
rid_t ping = conn.ping(); std::optional<Response<Buf_t>> response = conn.getResponse(ping);
-
std::string &
getError
()¶ Returns an error message for the last error occured during the execution of methods of the Connector and Connection classes.
Returns: an error message Rtype: std::string& Possible errors: none.
Example:
int rc = client.connect(conn, address, port); if (rc != 0) { std::cerr << conn.getError() << std::endl; return -1; }
-
void
reset
()¶ Resets a connection after errors, that is, cleans up the error message and the connection status.
Returns: none Rtype: none Possible errors: none.
Example:
if (client.wait(conn, ping, WAIT_TIMEOUT) != 0) { assert(conn.status.is_failed); std::cerr << conn.getError() << std::endl; conn.reset(); }
-
rid_t
ping
()¶ Prepares a request to ping a Tarantool instance.
The method encodes the request in the MessagePack format and queues it in the output connection buffer to be sent later by one of Connector’s methods, namely, wait(), waitAll(), or waitAny().
Returns the request ID that is used to get the response by the getResponce() method.
Returns: a request ID Rtype: rid_t Possible errors: none.
Example:
rid_t ping = conn.ping();
-
class
Space
: Connection¶ Space
is a nested class of the Connection class. It is a public wrapper to access the data-manipulation methods in the way similar to the Tarantool submodule box.space, like,space[space_id].select()
,space[space_id].replace()
, and so on.All the
Space
class methods listed below work in the following way:- A method encodes the corresponding request in the MessagePack format and queues it in the output connection buffer to be sent later by one of Connector’s methods, namely, wait(), waitAll(), or waitAny().
- A method returns the request ID. To get and read the actual data requested, first you need to get the response object by using the getResponce() method and then decode the data.
Public methods:
-
template<class
T
>
rid_tselect
(const T &key, uint32_t index_id = 0, uint32_t limit = UINT32_MAX, uint32_t offset = 0, IteratorType iterator = EQ)¶ Searches for a tuple or a set of tuples in the given space. The method works similar to space_object:select() and performs the search against the primary index (
index_id = 0
) by default. In other words,space[space_id].select()
equals tospace[space_id].index[0].select()
.Parameters: - key – value to be matched against the index key.
- index_id – index ID. Optional. Defaults to
0
. - limit – maximum number of tuples to select. Optional.
Defaults to
UINT32_MAX
. - offset – number of tuples to skip. Optional.
Defaults to
0
. - iterator – the type of iterator. Optional.
Defaults to
EQ
.
Returns: a request ID
Rtype: rid_t
Possible errors: none.
Example:
/* Equals to space_object:select({key_value}, {limit = 1}) in 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);
-
template<class
T
>
rid_treplace
(const T &tuple)¶ Inserts a tuple into the given space. If a tuple with the same primary key already exists,
replace()
replaces the existing tuple with a new one. The method works similar to space_object:replace() / put().Parameters: tuple – a tuple to insert. Returns: a request ID Rtype: rid_t Possible errors: none.
Example:
/* Equals to space_object:replace(key_value, "111", 1.01) in 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);
-
template<class
T
>
rid_tinsert
(const T &tuple)¶ Inserts a tuple into the given space. The method works similar to space_object:insert().
Parameters: tuple – a tuple to insert. Returns: a request ID Rtype: rid_t Possible errors: none.
Example:
/* Equals to space_object:insert(key_value, "112", 2.22) in 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);
-
template<class
K
, classT
>
rid_tupdate
(const K &key, const T &tuple, uint32_t index_id = 0)¶ Updates a tuple in the given space. The method works similar to space_object:update() and searches for the tuple to update against the primary index (
index_id = 0
) by default. In other words,space[space_id].update()
equals tospace[space_id].index[0].update()
.The
tuple
parameter specifies an update operation, an identifier of the field to update, and a new field value. The set of available operations and the format of specifying an operation and a field identifier is the same as in Tarantool. Refer to the description of :doc:` </reference/reference_lua/box_space/update>` and example below for details.Parameters: - key – value to be matched against the index key.
- tuple – parameters for the update operation, namely,
operator, field_identifier, value
. - index_id – index ID. Optional. Defaults to
0
.
Returns: a request ID
Rtype: rid_t
Possible errors: none.
Example:
/* Equals to space_object:update(key, {{'=', 1, 'update' }, {'+', 2, 12}}) in 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));
-
template<class
T
, classO
>
rid_tupsert
(const T &tuple, const O &ops, uint32_t index_base = 0)¶ Updates or inserts a tuple in the given space. The method works similar to space_object:upsert().
If there is an existing tuple that matches the key fields of
tuple
, the request has the same effect as update() and theops
parameter is used. If there is no existing tuple that matches the key fields oftuple
, the request has the same effect as insert() and thetuple
parameter is used.Parameters: - tuple – a tuple to insert.
- ops – parameters for the update operation, namely,
operator, field_identifier, value
. - index_base – starting number to count fields in a tuple:
0
or1
. Optional. Defaults to0
.
Returns: a request ID
Rtype: rid_t
Possible errors: none.
Example:
/* Equals to space_object:upsert({333, "upsert-insert", 0.0}, {{'=', 1, 'upsert-update'}}) in 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));
-
template<class
T
>
rid_tdelete_
(const T &key, uint32_t index_id = 0)¶ Deletes a tuple in the given space. The method works similar to space_object:delete() and searches for the tuple to delete against the primary index (
index_id = 0
) by default. In other words,space[space_id].delete_()
equals tospace[space_id].index[0].delete_()
.Parameters: - key – value to be matched against the index key.
- index_id – index ID. Optional. Defaults to
0
.
Returns: a request ID
Rtype: rid_t
Possible errors: none.
Example:
/* Equals to space_object:delete(123) in Tarantool*/ uint32_t space_id = 512; std::tuple key = std::make_tuple(123); rid_t f1 = conn.space[space_id].delete_(key);
-
class
Index
: Space¶ Index
is a nested class of the Space class. It is a public wrapper to access the data-manipulation methods in the way similar to the Tarantool submodule box.index, like,space[space_id].index[index_id].select()
and so on.All the
Index
class methods listed below work in the following way:- A method encodes the corresponding request in the MessagePack format and queues it in the output connection buffer to be sent later by one of Connector’s methods, namely, wait(), waitAll(), or waitAny().
- A method returns the request ID that is used to get the response by the getResponce() method. Refer to the getResponce() description to understand the response structure and how to read the requested data.
Public methods:
-
template<class
T
>
rid_tselect
(const T &key, uint32_t limit = UINT32_MAX, uint32_t offset = 0, IteratorType iterator = EQ)¶ This is an alternative to space.select(). The method searches for a tuple or a set of tuples in the given space against a particular index and works similar to index_object:select().
Parameters: - key – value to be matched against the index key.
- limit – maximum number of tuples to select. Optional.
Defaults to
UINT32_MAX
. - offset – number of tuples to skip. Optional.
Defaults to
0
. - iterator – the type of iterator. Optional.
Defaults to
EQ
.
Returns: a request ID
Rtype: rid_t
Possible errors: none.
Example:
/* Equals to index_object:select({key}, {limit = 1}) in 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);
-
template<class
K
, classT
>
rid_tupdate
(const K &key, const T &tuple)¶ This is an alternative to space.update(). The method updates a tuple in the given space but searches for the tuple against a particular index. The method works similar to index_object:update().
The
tuple
parameter specifies an update operation, an identifier of the field to update, and a new field value. The set of available operations and the format of specifying an operation and a field identifier is the same as in Tarantool. Refer to the description of :doc:` </reference/reference_lua/box_index/update>` and example below for details.Parameters: - key – value to be matched against the index key.
- tuple – parameters for the update operation, namely,
operator, field_identifier, value
.
Returns: a request ID
Rtype: rid_t
Possible errors: none.
Example:
/* Equals to index_object:update(key, {{'=', 1, 'update' }, {'+', 2, 12}}) in 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));
-
template<class
T
>
rid_tdelete_
(const T &key)¶ This is an alternative to space.delete_(). The method deletes a tuple in the given space but searches for the tuple against a particular index. The method works similar to index_object:delete().
Parameters: key – value to be matched against the index key. Returns: a request ID Rtype: rid_t Possible errors: none.
Example:
/* Equals to index_object:delete(123) in 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);