File Coverage

blib/lib/Async/Redis/Script.pm
Criterion Covered Total %
statement 14 43 32.5
branch 0 4 0.0
condition 0 10 0.0
subroutine 5 16 31.2
pod 10 11 90.9
total 29 84 34.5


line stmt bran cond sub pod time code
1             package Async::Redis::Script;
2              
3 73     73   569 use strict;
  73         173  
  73         3718  
4 73     73   401 use warnings;
  73         154  
  73         4480  
5 73     73   1240 use 5.018;
  73         283  
6              
7 73     73   413 use Future::AsyncAwait;
  73         152  
  73         699  
8 73     73   70771 use Digest::SHA qw(sha1_hex);
  73         418836  
  73         85053  
9              
10             sub new {
11 0     0 1   my ($class, %args) = @_;
12              
13 0           my $script = $args{script};
14 0 0         die "Script code required" unless defined $script;
15              
16             return bless {
17             redis => $args{redis},
18             script => $script,
19             sha => lc(sha1_hex($script)),
20             name => $args{name},
21             num_keys => $args{num_keys} // 'dynamic',
22             description => $args{description},
23 0   0       }, $class;
24             }
25              
26             # Accessors
27 0     0 1   sub sha { shift->{sha} }
28 0     0 1   sub script { shift->{script} }
29 0     0 1   sub name { shift->{name} }
30 0     0 1   sub num_keys { shift->{num_keys} }
31 0     0 1   sub description { shift->{description} }
32 0     0 0   sub redis { shift->{redis} }
33              
34             # Preferred entry point: run with explicit keys and args arrays
35             # Usage: $script->run(\@keys, \@args)
36 0     0 1   async sub run {
37 0           my ($self, $keys_aref, $args_aref) = @_;
38              
39 0   0       $keys_aref //= [];
40 0   0       $args_aref //= [];
41              
42 0           my $numkeys = scalar @$keys_aref;
43 0           return await $self->call_with_keys($numkeys, @$keys_aref, @$args_aref);
44             }
45              
46             # Run on a specific connection (for pipeline/pool support)
47             # Usage: $script->run_on($redis, \@keys, \@args)
48 0     0 1   async sub run_on {
49 0           my ($self, $redis, $keys_aref, $args_aref) = @_;
50              
51 0   0       $keys_aref //= [];
52 0   0       $args_aref //= [];
53              
54 0           my $numkeys = scalar @$keys_aref;
55              
56             return await $redis->evalsha_or_eval(
57             $self->{sha},
58             $self->{script},
59 0           $numkeys,
60             @$keys_aref,
61             @$args_aref,
62             );
63             }
64              
65             # Legacy: call with automatic key count detection
66             # Usage: $script->call('arg1', 'arg2')
67             # Assumes all args are ARGV (no KEYS)
68 0     0 1   async sub call {
69 0           my ($self, @args) = @_;
70 0           return await $self->call_with_keys(0, @args);
71             }
72              
73             # Legacy: call with explicit key count
74             # Usage: $script->call_with_keys($numkeys, @keys, @args)
75 0     0 1   async sub call_with_keys {
76 0           my ($self, $numkeys, @keys_and_args) = @_;
77              
78             my $redis = $self->{redis}
79 0 0         or die "No Redis connection - use run_on() or pass redis to constructor";
80              
81             return await $redis->evalsha_or_eval(
82             $self->{sha},
83             $self->{script},
84 0           $numkeys,
85             @keys_and_args,
86             );
87             }
88              
89             1;
90              
91             __END__