.\" 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 "MR::Tarantool::Box 3pm" .TH MR::Tarantool::Box 3pm "2020-07-21" "perl v5.30.3" "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" MR::Tarantool::Box \- A driver for an efficient Tarantool/Box NoSQL in\-memory storage. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 10 \& my $box = MR::Tarantool::Box\->new({ \& servers => "127.0.0.1:33013", \& name => "My Box", # mostly used for debug purposes \& spaces => [ { \& indexes => [ { \& index_name => \*(Aqidx1\*(Aq, \& keys => [0], \& }, { \& index_name => \*(Aqidx2\*(Aq, \& keys => [1,2], \& }, ], \& space => 1, # space id, as set in Tarantool/Box config \& name => "primary", # self\-descriptive space\-id \& format => "QqLlSsCc&$", # pack()\-compatible, Qq must be supported by perl itself, \& # & stands for byte\-string, $ stands for utf8 string. \& default_index => \*(Aqidx1\*(Aq, \& fields => [qw/ id f2 field3 f4 f5 f6 f7 f8 misc_string /], # turn each tuple into hash, field names according to format \& }, { \& #... \& } ], \& default_space => "primary", \& \& timeout => 1.0, # seconds \& retry => 3, \& debug => 9, # output to STDERR some debugging info \& raise => 0, # don\*(Aqt raise an exception in case of error \& }); \& \& my $bool = $box\->Insert(1, 2,3, 4,5,6,7,8,"asdf") or die $box\->ErrorStr; \& my $bool = $box\->Insert(2, 2,4, 4,5,6,7,8,"asdf",{space => "primary"}) or die $box\->ErrorStr; \& my $tuple = $box\->Insert(3, 3,3, 4,5,6,7,8,"asdf",{want_inserted_tuple => 1}) or die $box\->ErrorStr; \& \& # Select by single\-field key \& my $tuple = $box\->Select(1); # scalar context \- scalar result: $tuple \& my @tuples = $box\->Select(1,2,3); # list context \- list result: ($tuple, $tuple, ...) \& my $tuples = $box\->Select([1,2,3],{space => "primary", use_index => "idx1"}); # arrayref result: [$tuple, $tuple, ...] \& \& # Select by multi\-field key \& my $tuples = $box\->Select([[2,3]],{use_index => "idx2"}); # by full key \& my $tuples = $box\->Select([[2]] ,{use_index => "idx2"}); # by partial key \& \& my $bool = $box\->UpdateMulti(1,[ f4 => add => 3 ]); \& my $bool = $box\->UpdateMulti(2,[ f4 => add => 3 ],{space => "primary"}); \& my $tuple = $box\->UpdateMulti(3,[ f4 => add => 3 ],{want_updated_tuple => 1}); \& \& my $bool = $box\->Delete(1); \& my $tuple = $box\->Delete(2, {want_deleted_tuple => 1}); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" .SS "\s-1METHODS\s0" .IX Subsection "METHODS" \fInew\fR .IX Subsection "new" .PP .Vb 1 \& my $box = $class\->new(\e%args); .Ve .PP \&\f(CW%args:\fR .IP "\fBspaces\fR => [ \e%space, ... ]" 4 .IX Item "spaces => [ %space, ... ]" \&\f(CW%space:\fR .RS 4 .ie n .IP "\fBspace\fR => $space_id_uint32" 4 .el .IP "\fBspace\fR => \f(CW$space_id_uint32\fR" 4 .IX Item "space => $space_id_uint32" Space id as set in Tarantool/Box config. .ie n .IP "\fBname\fR => $space_name_string" 4 .el .IP "\fBname\fR => \f(CW$space_name_string\fR" 4 .IX Item "name => $space_name_string" Self-descriptive space id, which will be mapped into \f(CW\*(C`space\*(C'\fR. .ie n .IP "\fBformat\fR => $format_string" 4 .el .IP "\fBformat\fR => \f(CW$format_string\fR" 4 .IX Item "format => $format_string" \&\f(CW\*(C`pack()\*(C'\fR\-compatible tuple format string, allowed formats: \f(CW\*(C`QqLlSsC(c&$)*\*(C'\fR, where \f(CW\*(C`&\*(C'\fR stands for bytestring, \f(CW\*(C`$\*(C'\fR stands for \*(L"utf8\*(R" string. \f(CW\*(C`Qq\*(C'\fR usable only if perl supports int64 itself. Tuples' fields are packed/unpacked according to this \f(CW\*(C`format\*(C'\fR. \&\f(CW\*(C`*\*(C'\fR at the end of \f(CW\*(C`format\*(C'\fR enables \*(L"LongTuple\*(R". .IP "\fBhashify\fR => \fB\f(CB$coderef\fB\fR" 4 .IX Item "hashify => $coderef" Specify a callback to turn each tuple into a good-looking hash. It receives \f(CW\*(C`space\*(C'\fR id and resultset as arguments. No return value needed. .Sp .Vb 4 \& $coderef = sub { \& my ($space_id, $resultset) = @_; \& $_ = { FieldName1 => $_\->[0], FieldName2 => $_\->[1], ... } for @$resultset; \& }; .Ve .IP "\fBfields\fR => \fB\f(CB$arrayref\fB\fR" 4 .IX Item "fields => $arrayref" Specify an arrayref of fields names according to \f(CW\*(C`format\*(C'\fR to turn each tuple into a good-looking hash. Names must begin with \f(CW\*(C`[A\-Za\-z]\*(C'\fR. If \*(L"LongTuple\*(R" enabled, last field will be used to fold tailing fields. .IP "\fBlong_fields\fR => \fB\f(CB$arrayref\fB\fR" 4 .IX Item "long_fields => $arrayref" Specify an arrayref of fields names according to \f(CW\*(C`(xxx)*\*(C'\fR to turn tailing fields into a good-looking array of hashes. Names must begin with \f(CW\*(C`[A\-Za\-z]\*(C'\fR. Works with \*(L"LongTuple\*(R" enabled only. .IP "\fBindexes\fR => [ \e%index, ... ]" 4 .IX Item "indexes => [ %index, ... ]" \&\f(CW%index:\fR .RS 4 .ie n .IP "\fBid\fR => $index_id_uint32" 4 .el .IP "\fBid\fR => \f(CW$index_id_uint32\fR" 4 .IX Item "id => $index_id_uint32" Index id as set in Tarantool/Box config within current \f(CW\*(C`space\*(C'\fR. If not set, order position in \f(CW\*(C`indexes\*(C'\fR is theated as \f(CW\*(C`id\*(C'\fR. .ie n .IP "\fBname\fR => $index_name_string" 4 .el .IP "\fBname\fR => \f(CW$index_name_string\fR" 4 .IX Item "name => $index_name_string" Self-descriptive index id, which will be mapped into \f(CW\*(C`index_id\*(C'\fR. .ie n .IP "\fBkeys\fR => [ $field_no_uint32, ... ]" 4 .el .IP "\fBkeys\fR => [ \f(CW$field_no_uint32\fR, ... ]" 4 .IX Item "keys => [ $field_no_uint32, ... ]" Properly ordered arrayref of fields' numbers which are indexed. .RE .RS 4 .RE .ie n .IP "\fBdefault_index\fR => $default_index_name_string_or_id_uint32" 4 .el .IP "\fBdefault_index\fR => \f(CW$default_index_name_string_or_id_uint32\fR" 4 .IX Item "default_index => $default_index_name_string_or_id_uint32" Index \f(CW\*(C`id\*(C'\fR or \f(CW\*(C`name\*(C'\fR to be used by default for the current \f(CW\*(C`space\*(C'\fR in \fBselect\fR operations. Must be set if there are more than one \f(CW\*(C`\e%index\*(C'\fRes. .ie n .IP "\fBprimary_key_index\fR => $primary_key_name_string_or_id_uint32" 4 .el .IP "\fBprimary_key_index\fR => \f(CW$primary_key_name_string_or_id_uint32\fR" 4 .IX Item "primary_key_index => $primary_key_name_string_or_id_uint32" Index \f(CW\*(C`id\*(C'\fR or \f(CW\*(C`name\*(C'\fR to be used by default for the current \f(CW\*(C`space\*(C'\fR in \fBupdate\fR operations. It is set to \f(CW\*(C`default_index\*(C'\fR by default. .RE .RS 4 .RE .ie n .IP "\fBdefault_space\fR => $default_space_name_string_or_id_uint32" 4 .el .IP "\fBdefault_space\fR => \f(CW$default_space_name_string_or_id_uint32\fR" 4 .IX Item "default_space => $default_space_name_string_or_id_uint32" Space \f(CW\*(C`space\*(C'\fR or \f(CW\*(C`name\*(C'\fR to be used by default. Must be set if there are more than one \f(CW\*(C`\e%space\*(C'\fRs. .ie n .IP "\fBtimeout\fR => $timeout_fractional_seconds_float || 23" 4 .el .IP "\fBtimeout\fR => \f(CW$timeout_fractional_seconds_float\fR || 23" 4 .IX Item "timeout => $timeout_fractional_seconds_float || 23" A common timeout for network operations. .ie n .IP "\fBselect_timeout\fR => $select_timeout_fractional_seconds_float || 2" 4 .el .IP "\fBselect_timeout\fR => \f(CW$select_timeout_fractional_seconds_float\fR || 2" 4 .IX Item "select_timeout => $select_timeout_fractional_seconds_float || 2" Select queries timeout for network operations. See \*(L"select_retry\*(R". .ie n .IP "\fBretry\fR => $retry_int || 1" 4 .el .IP "\fBretry\fR => \f(CW$retry_int\fR || 1" 4 .IX Item "retry => $retry_int || 1" A common retries number for network operations. .ie n .IP "\fBselect_retry\fR => $select_retry_int || 3" 4 .el .IP "\fBselect_retry\fR => \f(CW$select_retry_int\fR || 3" 4 .IX Item "select_retry => $select_retry_int || 3" Select queries retries number for network operations. .Sp Sometimes we need short timeout for select's and long timeout for \fBcritical\fR update's, because in case of timeout we \fBdon't know if the update has succeeded\fR. For the same reason we \fBcan't retry\fR update operation. .Sp So increasing \f(CW\*(C`timeout\*(C'\fR and setting \f(CW\*(C`retry => 1\*(C'\fR for updates lowers possibility of such situations (but, of course, does not exclude them at all), and guarantees that we don't do the same more then once. .ie n .IP "\fBsoft_retry\fR => $soft_retry_int || 3" 4 .el .IP "\fBsoft_retry\fR => \f(CW$soft_retry_int\fR || 3" 4 .IX Item "soft_retry => $soft_retry_int || 3" A common retries number for Tarantool/Box \fBtemporary errors\fR (these marked by 1 in the lowest byte of \f(CW\*(C`error_code\*(C'\fR). In that case we \fBknow for sure\fR that the \fBrequest was declined\fR by Tarantool/Box for some reason (a tuple was locked for another update, for example), and we \fBcan\fR try it again. .Sp This is also limited by \f(CW\*(C`retry\*(C'\fR/\f(CW\*(C`select_retry\*(C'\fR (depending on query type). .ie n .IP "\fBretry_delay\fR => $retry_delay_fractional_seconds_float || 1" 4 .el .IP "\fBretry_delay\fR => \f(CW$retry_delay_fractional_seconds_float\fR || 1" 4 .IX Item "retry_delay => $retry_delay_fractional_seconds_float || 1" Specify a delay between retries for network operations. .ie n .IP "\fBraise\fR => $raise_bool || 1" 4 .el .IP "\fBraise\fR => \f(CW$raise_bool\fR || 1" 4 .IX Item "raise => $raise_bool || 1" Should we raise an exceptions? If so, exceptions are raised when no more retries left and all tries failed (with timeout, fatal, or temporary error). .ie n .IP "\fBdebug\fR => $debug_level_int || 0" 4 .el .IP "\fBdebug\fR => \f(CW$debug_level_int\fR || 0" 4 .IX Item "debug => $debug_level_int || 0" Debug level, 0 \- print nothing, 9 \- print everything .ie n .IP "\fBname\fR => $name" 4 .el .IP "\fBname\fR => \f(CW$name\fR" 4 .IX Item "name => $name" A string used for self-description. Mainly used for debugging purposes. .PP \fIError\fR .IX Subsection "Error" .PP Last error code, or 'fail' for some network reason, oftenly a timeout. .PP .Vb 1 \& $box\->Insert(@tuple) or die sprintf "Error %X", $box\->Error; # die "Error 202" .Ve .PP \fIErrorStr\fR .IX Subsection "ErrorStr" .PP Last error code and description in a single string. .PP .Vb 1 \& $box\->Insert(@tuple) or die $box\->ErrorStr; # die "Error 00000202: Illegal Parameters" .Ve .PP \fICall\fR .IX Subsection "Call" .PP Call a stored procedure. Returns an arrayref of the result tuple(s) upon success. .PP .Vb 2 \& my $results = $box\->Call(\*(Aqstored_procedure_name\*(Aq, \e@procedure_params, \e%options) or die $box\->ErrorStr; # Call failed \& my $result_tuple = @$results && $results\->[0] or warn "Call succeeded, but returned nothing"; .Ve .IP "\fB\f(CB@procedure_params\fB\fR" 4 .IX Item "@procedure_params" An array of bytestrings to be passed as is to the procecedure. .IP "\fB\f(CB%options\fB\fR" 4 .IX Item "%options" .RS 4 .PD 0 .IP "\fBunpack_format\fR" 4 .IX Item "unpack_format" .PD Format to unpack the result tuple, the same as \f(CW\*(C`format\*(C'\fR option for \f(CW\*(C`new()\*(C'\fR .RE .RS 4 .RE .PP \fIAdd, Insert, Replace\fR .IX Subsection "Add, Insert, Replace" .PP .Vb 3 \& $box\->Add(@tuple) or die $box\->ErrorStr; # only store a new tuple \& $box\->Replace(@tuple, { space => "secondary" }); # only store an existing tuple \& $box\->Insert(@tuple, { space => "main" }); # store anyway .Ve .PP Insert a \f(CW@tuple\fR into the storage into \f(CW$options{space}\fR or \f(CW\*(C`default_space\*(C'\fR space. All of them return \f(CW\*(C`true\*(C'\fR upon success. .PP All of them have the same parameters: .IP "\fB\f(CB@tuple\fB\fR" 4 .IX Item "@tuple" A tuple to insert. All fields must be defined. All fields will be \f(CW\*(C`pack()\*(C'\fRed according to \f(CW\*(C`format\*(C'\fR (see \*(L"new\*(R") .IP "\fB\f(CB%options\fB\fR" 4 .IX Item "%options" .RS 4 .PD 0 .ie n .IP "\fBspace\fR => $space_id_uint32_or_name_string" 4 .el .IP "\fBspace\fR => \f(CW$space_id_uint32_or_name_string\fR" 4 .IX Item "space => $space_id_uint32_or_name_string" .PD Specify storage space to work on. .RE .RS 4 .RE .PP The difference between them is the behaviour concerning tuple with the same primary key: .IP "\(bu" 4 \&\fBAdd\fR will succeed if and only if duplicate-key tuple \fBdoes not exist\fR .IP "\(bu" 4 \&\fBReplace\fR will succeed if and only if a duplicate-key tuple \fBexists\fR .IP "\(bu" 4 \&\fBInsert\fR will succeed \fBanyway\fR. Duplicate-key tuple will be \fBoverwritten\fR .PP \fISelect\fR .IX Subsection "Select" .PP Select tuple(s) from storage .PP .Vb 3 \& my $key = $id; \& my $key = [ $firstname, $lastname ]; \& my @keys = ($key, ...); \& \& my $tuple = $box\->Select($key) or $box\->Error && die $box\->ErrorStr; \& my $tuple = $box\->Select($key, \e%options) or $box\->Error && die $box\->ErrorStr; \& \& my @tuples = $box\->Select(@keys) or $box\->Error && die $box\->ErrorStr; \& my @tuples = $box\->Select(@keys, \e%options) or $box\->Error && die $box\->ErrorStr; \& \& my $tuples = $box\->Select(\e@keys) or die $box\->ErrorStr; \& my $tuples = $box\->Select(\e@keys, \e%options) or die $box\->ErrorStr; .Ve .IP "\fB\f(CB$key\fB\fR, \fB\f(CB@keys\fB\fR, \fB\e@keys\fR" 4 .IX Item "$key, @keys, @keys" Specify keys to select. All keys must be defined. .Sp Contextual behaviour: .RS 4 .IP "\(bu" 4 In scalar context, you can select one \f(CW$key\fR, and the resulting tuple will be returned. Check \f(CW\*(C`$box\->Error\*(C'\fR to see if there was an error or there is just no such key in the storage .IP "\(bu" 4 In list context, you can select several \f(CW@keys\fR, and the resulting tuples will be returned. Check \f(CW\*(C`$box\->Error\*(C'\fR to see if there was an error or there is just no such keys in the storage .IP "\(bu" 4 If you select \f(CW\*(C`\e@keys\*(C'\fR then \f(CW\*(C`\e@tuples\*(C'\fR will be returned upon success. \f(CW@tuples\fR will be empty if there are no such keys, and false will be returned in case of error. .RE .RS 4 .Sp Other notes: .IP "\(bu" 4 If you select using index on multiple fields each \f(CW$key\fR should be given as a key-tuple \f(CW\*(C`$key = [ $key_field1, $key_field2, ... ]\*(C'\fR. .RE .RS 4 .RE .IP "\fB\f(CB%options\fB\fR" 4 .IX Item "%options" .RS 4 .PD 0 .ie n .IP "\fBspace\fR => $space_id_uint32_or_name_string" 4 .el .IP "\fBspace\fR => \f(CW$space_id_uint32_or_name_string\fR" 4 .IX Item "space => $space_id_uint32_or_name_string" .PD Specify storage (by id or name) space to select from. .ie n .IP "\fBuse_index\fR => $index_id_uint32_or_name_string" 4 .el .IP "\fBuse_index\fR => \f(CW$index_id_uint32_or_name_string\fR" 4 .IX Item "use_index => $index_id_uint32_or_name_string" Specify index (by id or name) to use. .ie n .IP "\fBlimit\fR => $limit_uint32" 4 .el .IP "\fBlimit\fR => \f(CW$limit_uint32\fR" 4 .IX Item "limit => $limit_uint32" Max tuples to select. It is set to \f(CW\*(C`MAX_INT32\*(C'\fR by default. .ie n .IP "\fBraw\fR => $bool" 4 .el .IP "\fBraw\fR => \f(CW$bool\fR" 4 .IX Item "raw => $bool" Don't \f(CW\*(C`hashify\*(C'\fR (see \*(L"new\*(R"), disable \*(L"utf8\*(R" processing. .ie n .IP "\fBhash_by\fR => $by" 4 .el .IP "\fBhash_by\fR => \f(CW$by\fR" 4 .IX Item "hash_by => $by" Return a hashref of the resultset. If you \f(CW\*(C`hashify\*(C'\fR the result set, then \f(CW$by\fR must be a field name of the hash you return, otherwise it must be a number of field of the tuple. \&\f(CW\*(C`False\*(C'\fR will be returned in case of error. .RE .RS 4 .RE .PP \fIDelete\fR .IX Subsection "Delete" .PP Delete tuple from storage. Return false upon error. .PP .Vb 3 \& my $n_deleted = $box\->Delete($key) or die $box\->ErrorStr; \& my $n_deleted = $box\->Delete($key, \e%options) or die $box\->ErrorStr; \& warn "Nothing was deleted" unless int $n_deleted; \& \& my $deleted_tuple_set = $box\->Delete($key, { want_deleted_tuples => 1 }) or die $box\->ErrorStr; \& warn "Nothing was deleted" unless @$deleted_tuple_set; .Ve .IP "\fB\f(CB%options\fB\fR" 4 .IX Item "%options" .RS 4 .PD 0 .ie n .IP "\fBspace\fR => $space_id_uint32_or_name_string" 4 .el .IP "\fBspace\fR => \f(CW$space_id_uint32_or_name_string\fR" 4 .IX Item "space => $space_id_uint32_or_name_string" .PD Specify storage space (by id or name) to work on. .ie n .IP "\fBwant_deleted_tuple\fR => $bool" 4 .el .IP "\fBwant_deleted_tuple\fR => \f(CW$bool\fR" 4 .IX Item "want_deleted_tuple => $bool" if \f(CW$bool\fR then return deleted tuple. .RE .RS 4 .RE .PP \fIUpdateMulti\fR .IX Subsection "UpdateMulti" .PP Apply several update operations to a tuple. .PP .Vb 1 \& my @op = ([ f1 => add => 10 ], [ f1 => and => 0xFF], [ f2 => set => time() ], [ misc_string => cutend => 3 ]); \& \& my $n_updated = $box\->UpdateMulti($key, @op) or die $box\->ErrorStr; \& my $n_updated = $box\->UpdateMulti($key, @op, \e%options) or die $box\->ErrorStr; \& warn "Nothing was updated" unless int $n_updated; \& \& my $updated_tuple_set = $box\->UpdateMulti($key, @op, { want_result => 1 }) or die $box\->ErrorStr; \& warn "Nothing was updated" unless @$updated_tuple_set; .Ve .PP Different fields can be updated at one shot. The same field can be updated more than once. All update operations are done atomically. Returns false upon error. .ie n .IP "\fB\f(CB@op\fB\fR = ([ $field => $op => $value ], ...)" 4 .el .IP "\fB\f(CB@op\fB\fR = ([ \f(CW$field\fR => \f(CW$op\fR => \f(CW$value\fR ], ...)" 4 .IX Item "@op = ([ $field => $op => $value ], ...)" .RS 4 .PD 0 .IP "\fB\f(CB$field\fB\fR" 4 .IX Item "$field" .PD Field-to-update number or name (see \*(L"fields\*(R", \*(L"LongTuple\*(R"). .IP "\fB\f(CB$op\fB\fR" 4 .IX Item "$op" .RS 4 .PD 0 .IP "\fBset\fR" 4 .IX Item "set" .PD Set \f(CW$field\fR to \f(CW$value\fR .IP "\fBadd\fR, \fBand\fR, \fBxor\fR, \fBor\fR" 4 .IX Item "add, and, xor, or" Apply an arithmetic operation to \f(CW$field\fR with argument \f(CW$value\fR Currently arithmetic operations are supported only for int32 (4\-byte length) fields (and \f(CW$value\fRs too) .IP "\fBsplice\fR, \fBsubstr\fR" 4 .IX Item "splice, substr" Apply a perl-like splice operation to \f(CW$field\fR. \fB\f(CB$value\fB\fR = [$OFFSET, \f(CW$LENGTH\fR, \f(CW$REPLACE_WITH\fR]. substr is just an alias. .IP "\fBappend\fR, \fBprepend\fR" 4 .IX Item "append, prepend" Append or prepend \f(CW$field\fR with \f(CW$value\fR string. .IP "\fBcutbeg\fR, \fBcutend\fR" 4 .IX Item "cutbeg, cutend" Cut \f(CW$value\fR bytes from beginning or end of \f(CW$field\fR. .RE .RS 4 .RE .RE .RS 4 .RE .IP "\fB\f(CB%options\fB\fR" 4 .IX Item "%options" .RS 4 .PD 0 .ie n .IP "\fBspace\fR => $space_id_uint32_or_name_string" 4 .el .IP "\fBspace\fR => \f(CW$space_id_uint32_or_name_string\fR" 4 .IX Item "space => $space_id_uint32_or_name_string" .PD Specify storage space (by id or name) to work on. .ie n .IP "\fBwant_updated_tuple\fR => $bool" 4 .el .IP "\fBwant_updated_tuple\fR => \f(CW$bool\fR" 4 .IX Item "want_updated_tuple => $bool" if \f(CW$bool\fR then return updated tuple. .RE .RS 4 .RE .SS "AnyEvent" .IX Subsection "AnyEvent" \&\f(CW\*(C`Insert, UpdateMulti, Select, Delete, Call\*(C'\fR methods can be given the following options: .ie n .IP "\fBcallback\fR => sub { my ($data, $error) = @_; }" 4 .el .IP "\fBcallback\fR => sub { my ($data, \f(CW$error\fR) = \f(CW@_\fR; }" 4 .IX Item "callback => sub { my ($data, $error) = @_; }" Do an async request using AnyEvent. \&\f(CW$data\fR contains unpacked and processed according to request options data. \&\f(CW$error\fR contains a message string in case of error. Set up \f(CW\*(C`raise => 0\*(C'\fR to use this option. .ie n .SS """Continuations""" .el .SS "``Continuations''" .IX Subsection "Continuations" \&\f(CW\*(C`Select\*(C'\fR methods can be given the following options: .IP "\fBreturn_fh\fR => 1" 4 .IX Item "return_fh => 1" The request does only send operation on network, and returns \&\f(CW\*(C`{ fh => $IO_Handle, continue => $code }\*(C'\fR or false if send operation failed. \&\f(CW$code\fR reads data from network, unpacks, processes according to options and returns it. .Sp You should handle timeouts and retries manually (using \fBselect()\fR call for example). Usage example: .Sp .Vb 2 \& my $continuation = $box\->Select(13,{ return_fh => 1 }); \& ok $continuation, "select/continuation"; \& \& my $rin = \*(Aq\*(Aq; \& vec($rin,$continuation\->{fh}\->fileno,1) = 1; \& my $ein = $rin; \& ok 0 <= select($rin,undef,$ein,2), "select/continuation/select"; \& \& my $res = $continuation\->{continue}\->(); \& use Data::Dumper; \& is_deeply $res, [13, \*(Aqsome_email@test.mail.ru\*(Aq, 1, 2, 3, 4, \*(Aq123456789\*(Aq], "select/continuation/result"; .Ve .SS "LongTuple" .IX Subsection "LongTuple" If \f(CW\*(C`format\*(C'\fR given to \*(L"new\*(R", or \f(CW\*(C`unpack_format\*(C'\fR given to \*(L"Call\*(R" ends with a star (\f(CW\*(C`*\*(C'\fR) \&\fIlong tuple\fR is enabled. Last field or group of fields of \f(CW\*(C`format\*(C'\fR represent variable-length tail of the tuple. \f(CW\*(C`long_fields\*(C'\fR option given to \*(L"new\*(R" will fold the tail into array of hashes. .PP .Vb 3 \& $box\->Insert(1,"2",3); #1 \& $box\->Insert(3,"2",3,4,5); #2 \& $box\->Insert(5,"2",3,4,5,6,7); #3 .Ve .PP If we set up .PP .Vb 3 \& format => "L&CL*", \& fields => [qw/ a b c d /], # d is the folding field here \& # no long_fields \- no folding into hash .Ve .PP we'll get: .PP .Vb 6 \& $result = $box\->Select([1,2,3,4,5]); \& $result = [ \& { a => 1, b => "2", c => 3, d => [] }, #1 \& { a => 3, b => "2", c => 3, d => [4,5] }, #2 \& { a => 5, b => "2", c => 3, d => [4,5,6,7] }, #3 \& ]; .Ve .PP And if we set up .PP .Vb 3 \& format => "L&C(LL)*", \& fields => [qw/ a b c d /], # d is the folding field here \& long_fields => [qw/ d1 d2 /], .Ve .PP we'll get: .PP .Vb 5 \& $result = [ \& { a => 1, b => "2", c => 3, d => [] }, #1 \& { a => 3, b => "2", c => 3, d => [{d1=>4, d2=>5}] }, #2 \& { a => 5, b => "2", c => 3, d => [{d1=>4, d2=>5}, {d1=>6, d2=>7}] }, #3 \& ]; .Ve .PP \&\*(L"UpdateMulti\*(R" can be given a field number in several ways: .ie n .IP "$linear_index_int" 4 .el .IP "\f(CW$linear_index_int\fR" 4 .IX Item "$linear_index_int" .Vb 1 \& $box\->UpdateMulti(5, [ 5 => set => $val ]) #3: set 6 to $val .Ve .ie n .IP "an arrayref of [$index_of_folded_subtuple_int, $long_field_name_str_or_index_int]" 4 .el .IP "an arrayref of [$index_of_folded_subtuple_int, \f(CW$long_field_name_str_or_index_int\fR]" 4 .IX Item "an arrayref of [$index_of_folded_subtuple_int, $long_field_name_str_or_index_int]" .Vb 2 \& $box\->UpdateMulti(5, [ [1,0] => set => $val ]) #3: set 6 to $val \& $box\->UpdateMulti(5, [ [1,\*(Aqd1\*(Aq] => set => $val ]) #3: set 6 to $val .Ve .SS "utf8" .IX Subsection "utf8" Utf8 strings are supported very simply. When pushing any data to tarantool (with any query, read or write), the utf8 flag is set off, so all data is pushed as bytestring. When reading response, for fields marked a dollar sign \f(CW\*(C`$\*(C'\fR (see \*(L"new\*(R") (including such in \*(L"LongTuple\*(R" tail) utf8 flag is set on. That's all. Validity is on your own. .SH "LICENCE AND COPYRIGHT" .IX Header "LICENCE AND COPYRIGHT" This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "\(bu" 4 .IP "\(bu" 4 MR::Tarantool::Box::Singleton