.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "DR::Tarantool 3pm" .TH DR::Tarantool 3pm "2019-10-07" "perl v5.30.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" DR::Tarantool \- a Perl driver for Tarantool .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& use DR::Tarantool \*(Aq:constant\*(Aq, \*(Aqtarantool\*(Aq; \& use DR::Tarantool \*(Aq:all\*(Aq; \& \& my $tnt = tarantool \& host => \*(Aq127.0.0.1\*(Aq, \& port => 123, \& spaces => { \& ... \& } \& ; \& \& $tnt\->update( ... ); \& \& my $tnt = coro_tarantool \& host => \*(Aq127.0.0.1\*(Aq, \& port => 123, \& spaces => { \& ... \& } \& ; \& \& use DR::Tarantool \*(Aq:constant\*(Aq, \*(Aqasync_tarantool\*(Aq; \& \& async_tarantool \& host => \*(Aq127.0.0.1\*(Aq, \& port => 123, \& spaces => { \& ... \& }, \& sub { \& ... \& } \& ; \& \& $tnt\->update(...); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module provides a synchronous and asynchronous driver for Tarantool . .PP The driver does not have external dependencies, but includes the official light-weight Tarantool C client (a single C header which implements all protocol formatting) for packing requests and unpacking server responses. .PP This driver implements \*(L"iproto\*(R" protocol described in https://github.com/mailru/tarantool/blob/master/doc/box\-protocol.txt .PP It is built on top of AnyEvent \- an asynchronous event framework, and is therefore easiest to integrate into a program which is already based on AnyEvent. A synchronous version of the driver exists as well, it starts AnyEvent event machine for every request. .PP The driver supports three work flow types: .IP "DR::Tarantool::AsyncClient" 4 .IX Item "DR::Tarantool::AsyncClient" The primary type, provides an asynchronous, callback-based \&\s-1API.\s0 Requires a running AnyEvent machine. .IP "DR::Tarantool::SyncClient" 4 .IX Item "DR::Tarantool::SyncClient" Is built on top of DR::Tarantool::AsyncClient. Starts AnyEvent machine for every request. After a request is served, the event loop is stopped, and the results are returned to the caller, or, in case of an error, an exception is thrown. .IP "DR::Tarantool::CoroClient" 4 .IX Item "DR::Tarantool::CoroClient" Is also built on top of DR::Tarantool::AsyncClient, but is designed to work in cooperative multitasking environment provided by Coro. Is fully syntax-compatible with DR::Tarantool::SyncClient, but requires a running event loop to operate, like DR::Tarantool::AsyncClient. Requests from different coroutines are served concurrently. .PP Tarantool binary protocol contains no representation of database schema or tuple field types. Due to this deficiency, to easily integrate with Perl and automatically convert tuple fields to Perl values, the driver needs to know field names and types. To tell the driver about them, an instance of a dedicated class must be used. DR::Tarantool::Spaces is essentially a Perl hash which describes field types and names for each space used in the program. It can hardly be useful on its own, but once a connection is \&\*(L"enlightened\*(R" with an instance of this class, access to all tuple fields by a field name becomes possible. Type conversion, as well as packing/unpacking from Tarantool binary format is performed automatically. .PP Please follow the docs for DR::Tarantool::Spaces to learn how to describe a schema. .SS "Establishing a connection" .IX Subsection "Establishing a connection" \fIDR::Tarantool::AsyncClient\fR .IX Subsection "DR::Tarantool::AsyncClient" .PP .Vb 7 \& DR::Tarantool::AsyncClient\->connect( \& host => $host, \& port => $port, \& spaces => { ... }, \& sub { \& my ($tnt) = @_; \& ... \& \& } \& ); .Ve .PP The callback passed to \fBconnect()\fR gets invoked after a connection is established. The only argument of the callback is the newly established connection handle. The handle's type is DR::Tarantool::AsyncClient. .PP \fIDR::Tarantool::CoroClient and DR::Tarantool::SyncClient\fR .IX Subsection "DR::Tarantool::CoroClient and DR::Tarantool::SyncClient" .PP .Vb 5 \& my $tnt = DR::Tarantool::SyncClient\->connect( \& host => $host, \& port => $port, \& spaces => { ... } \& ); \& \& my $tnt = DR::Tarantool::CoroClient\->connect( \& host => $host, \& port => $port, \& spaces => { ... } \& ); .Ve .PP The only difference of synchronous versions from the asynchronous one is absence of a callback. The created connection handle is returned directly from \fBconnect()\fR. In this spirit, the only difference of any synchronous \s-1API\s0 all from the asynchronous counterpart is also in absence of the callback. .SS "Working with tuples" .IX Subsection "Working with tuples" \fIQuerying\fR .IX Subsection "Querying" .PP .Vb 1 \& my $user123 = $tnt\->select(\*(Aqusers\*(Aq => 123); \& \& my $users_by_roles = $tnt\->select(\*(Aqusers\*(Aq => \*(Aqadmins\*(Aq => \*(Aqrole_index\*(Aq); .Ve .PP It is possible to select data by a primary key (expects a Perl scalar), secondary, multi-part key (expects an array). .PP The default index used for selection is the primary one, a non-default index can be set by providing index name. .PP The contents of the result set is interpreted in accordance with schema description provided in DR::Tarantool::Spaces. Supported data types are numbers, Unicode strings, \s-1JSON,\s0 fixed-point decimals. .PP \fIInsertion\fR .IX Subsection "Insertion" .PP .Vb 1 \& $tnt\->insert(\*(Aqusers\*(Aq => [ 123, \*(Aqvasya\*(Aq, \*(Aqadmin\*(Aq ]); .Ve .PP Insert a tuple into space 'users', defined in \fBspaces\fR hash on connect. .PP \fIDeletion\fR .IX Subsection "Deletion" .PP .Vb 1 \& $tnt\->delete(users => 123); .Ve .PP Delete a tuple from space 'users'. The deletion is always performed by the primary key. .PP \fIUpdate\fR .IX Subsection "Update" .PP .Vb 1 \& $tnt\->update(users => 123 => [[ role => set => \*(Aqnot_admin\*(Aq ]]); .Ve .PP It is possible to modify any field in a tuple. A field can be accessed by field name or number. A set of modifications can be provided in a Perl array. .PP The following update operations are supported: .IP "set" 4 .IX Item "set" Assign a field .IP "add, and, or, xor" 4 .IX Item "add, and, or, xor" Arithmetic and bitwise operations for integers. .IP "substr" 4 .IX Item "substr" Replace a substring with a paste (similar to Perl splice). .IP "insert" 4 .IX Item "insert" Insert a field before the given field. .IP "delete" 4 .IX Item "delete" Delete a field. .IP "push" 4 .IX Item "push" Append a field at the tail of the tuple. .IP "pop" 4 .IX Item "pop" Pop a field from the tail of the tuple. .PP \fILua\fR .IX Subsection "Lua" .PP .Vb 1 \& $tnt\->call_lua(my_proc_name => [ arguments, ...]); .Ve .PP Invoke a Lua stored procedure by name. .SS "Supported data types" .IX Subsection "Supported data types" The driver supports all Tarantool types (\fB\s-1NUM\s0\fR, \fB\s-1NUM64\s0\fR, \fB\s-1STR\s0\fR), as well as some client-only types, which are converted to the above server types automatically on the client: .IP "\s-1UTF8STR\s0" 4 .IX Item "UTF8STR" A unicode string. .IP "\s-1MONEY\s0" 4 .IX Item "MONEY" Fixed decimal currency. Stores the value on the server in \fB\s-1NUM\s0\fR type, by multiplying the given amount by 100. The largest amount that can be stored in this type is, therefore, around 20 000 000. Can store negative values. .IP "\s-1BIGMONEY\s0" 4 .IX Item "BIGMONEY" The same as above, but uses \fB\s-1NUM64\s0\fR as the underlying storage. .IP "\s-1JSON\s0" 4 .IX Item "JSON" An arbitrary Perl object is automatically serialized to \s-1JSON\s0 with \&\s-1JSON::XS\s0 on insertion, and deserialized on selection. .PP The basic data transfer unit in Tarantool protocol is a single tuple. A selected tuple is automatically wrapped into an instance of class DR::Tarantool::Tuple. An object of this class can be used as an associative container, in which any field can be accessed by field name: .PP .Vb 1 \& my $user = $tnt\->select(users => 123); \& \& printf("user: %s, role: %s\en", $user\->name, $user\->role); .Ve .PP To run driver tests, the following Perl modules are also necessary: AnyEvent, Coro, Test::Pod, Test::Spelling, Devel::GlobalDestruction, \s-1JSON::XS\s0. .PP To run tests, do: perl Makefile.PL make make test .PP The test suite attempts to find the server and start it, thus make sure tarantool_box is available in the path, or export TARANTOOL_BOX=/path/to/tarantool_box. .SH "EXPORT" .IX Header "EXPORT" .SS "tarantool" .IX Subsection "tarantool" connects to Tarantool in synchronous mode using DR::Tarantool::SyncClient. .SS "rsync_tarantool" .IX Subsection "rsync_tarantool" connects to Tarantool in synchronous mode using DR::Tarantool::RealSyncClient. .SS "async_tarantool" .IX Subsection "async_tarantool" connects to tarantool in async mode using DR::Tarantool::AsyncClient. .SS "coro_tarantol" .IX Subsection "coro_tarantol" connects to tarantool in async mode using DR::Tarantool::CoroClient. .SS ":constant" .IX Subsection ":constant" Exports constants to use in a client request as flags: .IP "\s-1TNT_FLAG_RETURN\s0" 4 .IX Item "TNT_FLAG_RETURN" With this flag on, each \s-1INSERT/UPDATE\s0 request returns the new value of the tuple. \s-1DELETE\s0 returns the deleted tuple, if it is found. .IP "\s-1TNT_FLAG_ADD\s0" 4 .IX Item "TNT_FLAG_ADD" With this flag on, \s-1INSERT\s0 returns an error if an old tuple with the same primary key already exists. No tuple is inserted in this case. .IP "\s-1TNT_FLAG_REPLACE\s0" 4 .IX Item "TNT_FLAG_REPLACE" With this flag on, \s-1INSERT\s0 returns an error if an old tuple for the primary key does not exist. Without either of the flags, \s-1INSERT\s0 replaces the old tuple if it doesn't exist. .SS ":all" .IX Subsection ":all" Exports all functions and constants. .SH "TODO" .IX Header "TODO" .IP "\(bu" 4 Support push, pop in \s-1UPDATE.\s0 .IP "\(bu" 4 Make it possible to construct \fBselect\fR, \fBdelete\fR keys from Perl hashes, not just Perl arrays. .IP "\(bu" 4 Support DR::Tarantool::Tuple as an argument to \fBinsert\fR. .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" .Vb 2 \& Copyright (C) 2011 Dmitry E. Oboukhov \& Copyright (C) 2011 Roman V. Nikolaev \& \& This program is free software, you can redistribute it and/or \& modify it under the terms of the Artistic License. .Ve .SH "VCS" .IX Header "VCS" The project is hosted on github in the following git repository: .