Provided by: libmr-tarantool-perl_0.0.24-2_all bug

NAME

       MR::Tarantool::Box - A driver for an efficient Tarantool/Box NoSQL in-memory storage.

SYNOPSIS

           my $box = MR::Tarantool::Box->new({
               servers => "127.0.0.1:33013",
               name    => "My Box",              # mostly used for debug purposes
               spaces => [ {
                   indexes => [ {
                       index_name   => 'idx1',
                       keys         => [0],
                   }, {
                       index_name   => 'idx2',
                       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 => 'idx1',
                   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't 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});

DESCRIPTION

   METHODS
       new

           my $box = $class->new(\%args);

       %args:

       spaces => [ \%space, ... ]
           %space:

           space => $space_id_uint32
               Space id as set in Tarantool/Box config.

           name => $space_name_string
               Self-descriptive space id, which will be mapped into "space".

           format => $format_string
               "pack()"-compatible  tuple  format string, allowed formats: "QqLlSsC(c&$)*", where "&" stands for
               bytestring, "$" stands for "utf8" string. "Qq" usable only if perl supports int64 itself. Tuples'
               fields are packed/unpacked according to this "format".   "*"  at  the  end  of  "format"  enables
               "LongTuple".

           hashify => $coderef
               Specify  a  callback  to  turn  each  tuple into a good-looking hash.  It receives "space" id and
               resultset as arguments. No return value needed.

                   $coderef = sub {
                       my ($space_id, $resultset) = @_;
                       $_ = { FieldName1 => $_->[0], FieldName2 => $_->[1], ... } for @$resultset;
                   };

           fields => $arrayref
               Specify an arrayref of fields names according to "format" to turn each tuple into a  good-looking
               hash.  Names must begin with "[A-Za-z]".  If "LongTuple" enabled, last field will be used to fold
               tailing fields.

           long_fields => $arrayref
               Specify an arrayref of fields names according to "(xxx)*" to turn tailing  fields  into  a  good-
               looking array of hashes.  Names must begin with "[A-Za-z]".  Works with "LongTuple" enabled only.

           indexes => [ \%index, ... ]
               %index:

               id => $index_id_uint32
                   Index  id  as set in Tarantool/Box config within current "space".  If not set, order position
                   in "indexes" is theated as "id".

               name => $index_name_string
                   Self-descriptive index id, which will be mapped into "index_id".

               keys => [ $field_no_uint32, ... ]
                   Properly ordered arrayref of fields' numbers which are indexed.

           default_index => $default_index_name_string_or_id_uint32
               Index "id" or "name" to be used by default for the current "space" in select operations.  Must be
               set if there are more than one "\%index"es.

           primary_key_index => $primary_key_name_string_or_id_uint32
               Index "id" or "name" to be used by default for the current "space" in update operations.   It  is
               set to "default_index" by default.

       default_space => $default_space_name_string_or_id_uint32
           Space "space" or "name" to be used by default. Must be set if there are more than one "\%space"s.

       timeout => $timeout_fractional_seconds_float || 23
           A common timeout for network operations.

       select_timeout => $select_timeout_fractional_seconds_float || 2
           Select queries timeout for network operations. See "select_retry".

       retry => $retry_int || 1
           A common retries number for network operations.

       select_retry => $select_retry_int || 3
           Select queries retries number for network operations.

           Sometimes  we need short timeout for select's and long timeout for critical update's, because in case
           of timeout we don't know if the update has succeeded. For the  same  reason  we  can't  retry  update
           operation.

           So  increasing  "timeout"  and setting "retry => 1" 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.

       soft_retry => $soft_retry_int || 3
           A  common  retries number for Tarantool/Box temporary errors (these marked by 1 in the lowest byte of
           "error_code"). In that case we know for sure that the request was declined by Tarantool/Box for  some
           reason (a tuple was locked for another update, for example), and we can try it again.

           This is also limited by "retry"/"select_retry" (depending on query type).

       retry_delay => $retry_delay_fractional_seconds_float || 1
           Specify a delay between retries for network operations.

       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).

       debug => $debug_level_int || 0
           Debug level, 0 - print nothing, 9 - print everything

       name => $name
           A string used for self-description. Mainly used for debugging purposes.

       Error

       Last error code, or 'fail' for some network reason, oftenly a timeout.

           $box->Insert(@tuple) or die sprintf "Error %X", $box->Error; # die "Error 202"

       ErrorStr

       Last error code and description in a single string.

           $box->Insert(@tuple) or die $box->ErrorStr;                  # die "Error 00000202: Illegal Parameters"

       Call

       Call a stored procedure. Returns an arrayref of the result tuple(s) upon success.

           my $results = $box->Call('stored_procedure_name', \@procedure_params, \%options) or die $box->ErrorStr; # Call failed
           my $result_tuple = @$results && $results->[0] or warn "Call succeeded, but returned nothing";

       @procedure_params
           An array of bytestrings to be passed as is to the procecedure.

       %options
           unpack_format
               Format to unpack the result tuple, the same as "format" option for "new()"

       Add, Insert, Replace

           $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

       Insert a @tuple into the storage into $options{space} or  "default_space"  space.   All  of  them  return
       "true" upon success.

       All of them have the same parameters:

       @tuple
           A  tuple  to  insert. All fields must be defined. All fields will be "pack()"ed according to "format"
           (see "new")

       %options
           space => $space_id_uint32_or_name_string
               Specify storage space to work on.

       The difference between them is the behaviour concerning tuple with the same primary key:

       •   Add will succeed if and only if duplicate-key tuple does not existReplace will succeed if and only if a duplicate-key tuple existsInsert will succeed anyway. Duplicate-key tuple will be overwritten

       Select

       Select tuple(s) from storage

           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, \%options)   or $box->Error && die $box->ErrorStr;

           my @tuples = $box->Select(@keys)             or $box->Error && die $box->ErrorStr;
           my @tuples = $box->Select(@keys, \%options)  or $box->Error && die $box->ErrorStr;

           my $tuples = $box->Select(\@keys)            or die $box->ErrorStr;
           my $tuples = $box->Select(\@keys, \%options) or die $box->ErrorStr;

       $key, @keys, \@keys
           Specify keys to select. All keys must be defined.

           Contextual behaviour:

           •   In scalar context, you can select one $key, and the resulting  tuple  will  be  returned.   Check
               "$box->Error" to see if there was an error or there is just no such key in the storage

           •   In  list context, you can select several @keys, and the resulting tuples will be returned.  Check
               "$box->Error" to see if there was an error or there is just no such keys in the storage

           •   If you select "\@keys" then "\@tuples" will be returned upon success. @tuples will  be  empty  if
               there are no such keys, and false will be returned in case of error.

           Other notes:

           •   If  you  select using index on multiple fields each $key should be given as a key-tuple "$key = [
               $key_field1, $key_field2, ... ]".

       %options
           space => $space_id_uint32_or_name_string
               Specify storage (by id or name) space to select from.

           use_index => $index_id_uint32_or_name_string
               Specify index (by id or name) to use.

           limit => $limit_uint32
               Max tuples to select. It is set to "MAX_INT32" by default.

           raw => $bool
               Don't "hashify" (see "new"), disable "utf8" processing.

           hash_by => $by
               Return a hashref of the resultset. If you "hashify" the result set, then $by must be a field name
               of the hash you return, otherwise it must be a number of field of the  tuple.   "False"  will  be
               returned in case of error.

       Delete

       Delete tuple from storage. Return false upon error.

           my $n_deleted = $box->Delete($key) or die $box->ErrorStr;
           my $n_deleted = $box->Delete($key, \%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;

       %options
           space => $space_id_uint32_or_name_string
               Specify storage space (by id or name) to work on.

           want_deleted_tuple => $bool
               if $bool then return deleted tuple.

       UpdateMulti

       Apply several update operations to a tuple.

           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, \%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;

       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.

       @op = ([ $field => $op => $value ], ...)
           $field
               Field-to-update number or name (see "fields", "LongTuple").

           $op
               set Set $field to $value

               add, and, xor, or
                   Apply an arithmetic operation to $field with argument $value Currently arithmetic  operations
                   are supported only for int32 (4-byte length) fields (and $values too)

               splice, substr
                   Apply  a  perl-like  splice  operation to $field. $value = [$OFFSET, $LENGTH, $REPLACE_WITH].
                   substr is just an alias.

               append, prepend
                   Append or prepend $field with $value string.

               cutbeg, cutend
                   Cut $value bytes from beginning or end of $field.

       %options
           space => $space_id_uint32_or_name_string
               Specify storage space (by id or name) to work on.

           want_updated_tuple => $bool
               if $bool then return updated tuple.

   AnyEvent
       "Insert, UpdateMulti, Select, Delete, Call" methods can be given the following options:

       callback => sub { my ($data, $error) = @_; }
           Do an async request using AnyEvent.  $data contains  unpacked  and  processed  according  to  request
           options  data.   $error  contains a message string in case of error.  Set up "raise => 0" to use this
           option.

   "Continuations"
       "Select" methods can be given the following options:

       return_fh => 1
           The request does only send operation on network, and returns "{ fh => $IO_Handle, continue  =>  $code
           }" or false if send operation failed.  $code reads data from network, unpacks, processes according to
           options and returns it.

           You should handle timeouts and retries manually (using select() call for example).  Usage example:

               my $continuation = $box->Select(13,{ return_fh => 1 });
               ok $continuation, "select/continuation";

               my $rin = '';
               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, 'some_email@test.mail.ru', 1, 2, 3, 4, '123456789'], "select/continuation/result";

   LongTuple
       If  "format"  given  to  "new",  or  "unpack_format" given to "Call" ends with a star ("*") long tuple is
       enabled. Last field or group  of  fields  of  "format"  represent  variable-length  tail  of  the  tuple.
       "long_fields" option given to "new" will fold the tail into array of hashes.

           $box->Insert(1,"2",3);         #1
           $box->Insert(3,"2",3,4,5);     #2
           $box->Insert(5,"2",3,4,5,6,7); #3

       If we set up

           format => "L&CL*",
           fields => [qw/ a b c d /], # d is the folding field here
           # no long_fields - no folding into hash

       we'll get:

           $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
           ];

       And if we set up

           format => "L&C(LL)*",
           fields => [qw/ a b c d /], # d is the folding field here
           long_fields => [qw/ d1 d2 /],

       we'll get:

           $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
           ];

       "UpdateMulti" can be given a field number in several ways:

       $linear_index_int
               $box->UpdateMulti(5, [ 5 => set => $val ]) #3: set 6 to $val

       an arrayref of [$index_of_folded_subtuple_int, $long_field_name_str_or_index_int]
               $box->UpdateMulti(5, [ [1,0]    => set => $val ]) #3: set 6 to $val
               $box->UpdateMulti(5, [ [1,'d1'] => set => $val ]) #3: set 6 to $val

   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 "$" (see "new") (including such in "LongTuple" tail) utf8 flag is set on.  That's
       all. Validity is on your own.

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.

SEE ALSO

       •   <http://tarantool.org>

       •   MR::Tarantool::Box::Singleton

perl v5.30.3                                       2020-07-21                            MR::Tarantool::Box(3pm)