| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package RedisDB::Parser; |
|
2
|
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
240289
|
use strict; |
|
|
3
|
|
|
|
|
20
|
|
|
|
3
|
|
|
|
|
65
|
|
|
4
|
3
|
|
|
3
|
|
12
|
use warnings; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
109
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = "2.23"; |
|
6
|
|
|
|
|
|
|
$VERSION = eval $VERSION; |
|
7
|
|
|
|
|
|
|
|
|
8
|
3
|
|
|
3
|
|
782
|
use Try::Tiny; |
|
|
3
|
|
|
|
|
3107
|
|
|
|
3
|
|
|
|
|
449
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
my $implementation; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
unless ( $ENV{REDISDB_PARSER_PP} ) { |
|
13
|
|
|
|
|
|
|
try { |
|
14
|
|
|
|
|
|
|
require RedisDB::Parser::XS; |
|
15
|
|
|
|
|
|
|
$implementation = "RedisDB::Parser::XS"; |
|
16
|
|
|
|
|
|
|
} |
|
17
|
|
|
|
|
|
|
} |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
unless ($implementation) { |
|
20
|
|
|
|
|
|
|
require RedisDB::Parser::PP; |
|
21
|
|
|
|
|
|
|
$implementation = "RedisDB::Parser::PP"; |
|
22
|
|
|
|
|
|
|
} |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=head1 NAME |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
RedisDB::Parse::Redis - redis protocol parser for RedisDB |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
use RedisDB::Parser; |
|
31
|
|
|
|
|
|
|
my $parser = RedisDB::Parser->new( master => $ref ); |
|
32
|
|
|
|
|
|
|
$parser->push_callback(\&cb); |
|
33
|
|
|
|
|
|
|
$parser->parse($data); |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
This module provides methods to build redis requests and parse replies from |
|
38
|
|
|
|
|
|
|
the server. |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=head1 METHODS |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head2 $class->new(%params) |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
Creates new parser object. Following parameters may be specified: |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=over 4 |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=item B |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
Arbitrary reference. It is passed to callbacks as the first argument. Normally |
|
51
|
|
|
|
|
|
|
it would be a reference to the object managing connection to redis-server. |
|
52
|
|
|
|
|
|
|
Reference is weakened. |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=item B |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
Module allows you to set a separate callback for every new message. If there |
|
57
|
|
|
|
|
|
|
are no callbacks in queue, default_callback will be used. |
|
58
|
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=item B |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
If this parameter is set all data will be encoded as UTF-8 when building |
|
62
|
|
|
|
|
|
|
requests, and decoded from UTF-8 when parsing replies. By default module |
|
63
|
|
|
|
|
|
|
expects all data to be octet sequences. |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=item B |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
If parsed message is an error message, parser will create object of the |
|
68
|
|
|
|
|
|
|
specified class with the message as the only constructor argument, and pass |
|
69
|
|
|
|
|
|
|
this object to the callback. By default L class is |
|
70
|
|
|
|
|
|
|
used. |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=back |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=cut |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub new { |
|
77
|
1
|
|
|
1
|
1
|
3845
|
shift; |
|
78
|
1
|
|
|
|
|
6
|
return $implementation->new(@_); |
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=head2 $class->implementation |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
Returns name of the package that actually implements parser functionality. It |
|
84
|
|
|
|
|
|
|
may be either L or L. |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=cut |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub implementation { |
|
89
|
2
|
|
|
2
|
1
|
2213
|
return $implementation; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 $self->build_request($command, @arguments) |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Encodes I<$command> and I<@arguments> as redis request. |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=head2 $self->push_callback(\&cb) |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Pushes callback to the queue of callbacks. |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head2 $self->set_default_callback(\&cb) |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
Set callback to invoke when there are no callbacks in queue. |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head2 $self->callbacks |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
Returns true if there are callbacks in queue |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=head2 $self->propagate_reply($reply) |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Invoke every callback from queue and the default callback with the given |
|
111
|
|
|
|
|
|
|
I<$reply>. Can be used e.g. if connection to server has been lost to invoke |
|
112
|
|
|
|
|
|
|
every callback with error message. |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head2 $self->parse($data) |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
Process new data received from the server. For every new reply method will |
|
117
|
|
|
|
|
|
|
invoke callback, either the one from the queue that was added using |
|
118
|
|
|
|
|
|
|
I method, or default callback if the queue is empty. Callback |
|
119
|
|
|
|
|
|
|
passed two arguments: master value, and decoded reply from the server. |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
Method returns the number of parsed replies. |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=cut |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head1 PARSING |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
Here's how the parser represents replies from redis-server: |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head2 Status reply |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
Status replies are represented by string values without the initial plus sign |
|
132
|
|
|
|
|
|
|
and final end of the line symbols. I.e. "+OK" reply from the server will be |
|
133
|
|
|
|
|
|
|
parsed into "OK" string that will be passed to callback. |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=head2 Error reply |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Error replies are represents as objects of I, which is by default |
|
138
|
|
|
|
|
|
|
L. If parser detects error reply, it strips it off |
|
139
|
|
|
|
|
|
|
initial minus sign and final end of the line, and then passes result as sole |
|
140
|
|
|
|
|
|
|
argument to the I method of the I. This is the only case when |
|
141
|
|
|
|
|
|
|
parser produces blessed reference, and so callback may easily detect error |
|
142
|
|
|
|
|
|
|
condition by checking this. |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=head2 Integer reply |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Parser represents integer reply as a scalar value |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=head2 Bulk reply |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Parser represents bulk replies as scalar values. By default it treats result as |
|
151
|
|
|
|
|
|
|
a sequence of bytes, but if I options is set it decodes result from UTF-8 |
|
152
|
|
|
|
|
|
|
and may croak if result is not a valid UTF-8 sequence. NULL bulk reply is |
|
153
|
|
|
|
|
|
|
represented as undefined value. |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=head2 Multi-bulk reply |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
Multi-bulk replies are returned as array references. Empty multi-bulk reply is |
|
158
|
|
|
|
|
|
|
represented as reference to empty array. Null multi-bulk reply is represented |
|
159
|
|
|
|
|
|
|
as undefined scalar. |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=cut |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
1; |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
__END__ |