Options to pass to L<MR::Taranatool::Box->Call|MR::Taranatool::Box/Call> method.
=item B<params> => \@names
Procedure input parameters' names
=item B<params_default> => \@defaults
Procedure input parameters default values. Undefined or absent value makes
its parameter mandatory.
=item B<params_format> => \@format
C<< pack() >>-compatible format to pack input parameters. Must match C<params>.
=item B<unpack_format> => \@format
C<< pack() >>-compatible format to unpack procedure output.
=back
=item B<%sp_params>:
C<< Name => $value >> pairs.
=item B<%optional_options>:
Options to pass to L<MR::Taranatool::Box->Call|MR::Taranatool::Box/Call> method.
This overrides C<< %options >> values key-by-key.
=back
=cut
subdeclare_stored_procedure {
my($class, %opts) = @_;
my$name= delete$opts{name} or confess "No `name` given";
my$options= $opts{options} || {};
confess "no `params` given; it must be an arrayref"if!exists$opts{params} or ref$opts{params} ne 'ARRAY';
my@params= @{$opts{params}};
my$pack;
if(my$fn= $opts{pack}) {
confess "`params_format` and `params_default` are not applicable while `pack` is in use"ifexists$opts{params_format} or exists$opts{params_default};
if(ref$fn) {
confess "`pack` can be code ref or a method name, nothing else"unlessref$fneq 'CODE';
$pack= $fn;
} else{
confess "`pack` method $fn is not provided by class ${class}"unless$class->can($fn);
$pack= sub{ $class->$fn(@_) };
}
} else{
confess "no `pack` nor `params_format` given; it must be an arrayref with number of elements exactly as in `params`"if!exists$opts{params_format} or ref$opts{params_format} ne 'ARRAY'or @{$opts{params_format}} != @params;
confess "`params_default` is given but it must be an arrayref with number of elements no more then in `params`"ifexists$opts{params_format} and (ref$opts{params_format} ne 'ARRAY'or @{$opts{params_format}} > @params);
my@fmt= @{$opts{params_format}};
my@def= @{$opts{params_default}||[]};
$pack= sub{
my$p= $_[0];
formy$i(0..$#params) {
$p->[$i] = $def[$i] if!defined$p->[$i] and $i< @def;
confess "All params must be defined"unlessdefined$p->[$i];
$p->[$i] = pack$fmt[$i], $p->[$i];
}
return$p;
};
}
my$unpack;
if(my$fn= $opts{unpack}) {
if(ref$fn) {
confess "`unpack` can be code ref or a method name, nothing else"unlessref$fneq 'CODE';
$unpack= $fn;
} else{
confess "`unpack` method $fn is not provided by class ${class}"unless$class->can($fn);
$unpack= sub{ $class->$fn(@_) };
}
$options->{unpack_format} = [ "a*"];
} else{
confess "no `unpack` nor `unpack_format` given; it must be an arrayref"if!exists$opts{unpack_format} or ref$opts{unpack_format} ne 'ARRAY';
my$f= $opts{unpack_format};
$options->{unpack_format} = $f;
}
my$method= $opts{method_name} or confess "`method_name` not given";