line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Data::Riak::Fast::Bucket; |
2
|
|
|
|
|
|
|
# ABSTRACT: A Data::Riak::Fast bucket, used for storing keys and values. |
3
|
|
|
|
|
|
|
|
4
|
22
|
|
|
22
|
|
880
|
use Mouse; |
|
22
|
|
|
|
|
34442
|
|
|
22
|
|
|
|
|
126
|
|
5
|
|
|
|
|
|
|
|
6
|
22
|
|
|
22
|
|
11951
|
use Data::Riak::Fast::Link; |
|
22
|
|
|
|
|
43
|
|
|
22
|
|
|
|
|
517
|
|
7
|
22
|
|
|
22
|
|
14597
|
use Data::Riak::Fast::Util::MapCount; |
|
22
|
|
|
|
|
60
|
|
|
22
|
|
|
|
|
892
|
|
8
|
22
|
|
|
22
|
|
20650
|
use Data::Riak::Fast::Util::ReduceCount; |
|
22
|
|
|
|
|
64
|
|
|
22
|
|
|
|
|
849
|
|
9
|
|
|
|
|
|
|
|
10
|
22
|
|
|
22
|
|
12937
|
use Data::Riak::Fast::MapReduce; |
|
22
|
|
|
|
|
122
|
|
|
22
|
|
|
|
|
805
|
|
11
|
22
|
|
|
22
|
|
143
|
use Data::Riak::Fast::MapReduce::Phase::Reduce; |
|
22
|
|
|
|
|
47
|
|
|
22
|
|
|
|
|
440
|
|
12
|
|
|
|
|
|
|
|
13
|
22
|
|
|
22
|
|
25107
|
use HTTP::Headers::ActionPack::LinkList; |
|
22
|
|
|
|
|
44489
|
|
|
22
|
|
|
|
|
732
|
|
14
|
|
|
|
|
|
|
|
15
|
22
|
|
|
22
|
|
138
|
use JSON::XS qw/decode_json encode_json/; |
|
22
|
|
|
|
|
42
|
|
|
22
|
|
|
|
|
35467
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
with 'Data::Riak::Fast::Role::HasRiak'; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 DESCRIPTION |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Data::Riak::Fast::Bucket is the primary interface that most people will use for Riak. |
22
|
|
|
|
|
|
|
Adding and removing keys and values, adding links, querying keys; all of those |
23
|
|
|
|
|
|
|
happen here. |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 SYNOPSIS |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my $bucket = Data::Riak::Fast::Bucket->new({ |
28
|
|
|
|
|
|
|
name => 'my_bucket', |
29
|
|
|
|
|
|
|
riak => $riak |
30
|
|
|
|
|
|
|
}); |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# Sets the value of "foo" to "bar", in my_bucket. |
33
|
|
|
|
|
|
|
$bucket->add('foo', 'bar'); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Gets the Result object for "foo" in my_bucket. |
36
|
|
|
|
|
|
|
my $foo = $bucket->get('foo'); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# Returns "bar" |
39
|
|
|
|
|
|
|
my $value = $foo->value; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
$bucket->create_alias({ key => 'foo', as => 'alias_to_foo' }); |
42
|
|
|
|
|
|
|
$bucket->create_alias({ key => 'foo', as => 'alias_to_foo', in => $another_bucket }); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# Returns "bar" |
45
|
|
|
|
|
|
|
my $value = $bucket->resolve_alias('alias_to_foo'); |
46
|
|
|
|
|
|
|
my $value = $another_bucket->resolve_alias('alias_to_foo'); |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
$bucket->add('baz, 'value of baz', { links => [$bucket->create_link( riaktag => 'buddy', key =>'foo' )] }); |
49
|
|
|
|
|
|
|
my $resultset = $bucket->linkwalk('baz', [[ 'buddy', '_' ]]); |
50
|
|
|
|
|
|
|
my $value = $resultset->first->value; # Will be "bar", the value of foo |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
=cut |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
has name => ( |
55
|
|
|
|
|
|
|
is => 'ro', |
56
|
|
|
|
|
|
|
isa => 'Str', |
57
|
|
|
|
|
|
|
required => 1 |
58
|
|
|
|
|
|
|
); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head1 METHOD |
61
|
|
|
|
|
|
|
=head2 add ($key, $value, $opts) |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
This will insert a key C<$key> into the bucket, with value C<$value>. The C<$opts> |
64
|
|
|
|
|
|
|
can include links, allowed content types, or queries. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=cut |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
sub add { |
69
|
0
|
|
|
0
|
0
|
|
my ($self, $key, $value, $opts) = @_; |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
0
|
|
|
|
$opts ||= {}; |
72
|
|
|
|
|
|
|
|
73
|
0
|
|
|
|
|
|
my $pack = HTTP::Headers::ActionPack::LinkList->new; |
74
|
0
|
0
|
|
|
|
|
if($opts->{'links'}) { |
75
|
0
|
|
|
|
|
|
foreach my $link (@{$opts->{'links'}}) { |
|
0
|
|
|
|
|
|
|
76
|
0
|
0
|
0
|
|
|
|
if(blessed $link && $link->isa('Data::Riak::Fast::Link')) { |
77
|
0
|
|
|
|
|
|
$pack->add($link->as_link_header); |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
else { |
80
|
0
|
|
|
|
|
|
confess "Bad link type ($link)"; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# TODO: |
86
|
|
|
|
|
|
|
# need to support other headers |
87
|
|
|
|
|
|
|
# X-Riak-Vclock if the object already exists, the vector clock attached to the object when read. |
88
|
|
|
|
|
|
|
# X-Riak-Meta-* - any additional metadata headers that should be stored with the object. |
89
|
|
|
|
|
|
|
# see http://wiki.basho.com/HTTP-Store-Object.html |
90
|
|
|
|
|
|
|
# - SL |
91
|
|
|
|
|
|
|
|
92
|
0
|
0
|
|
|
|
|
my $resultset = $self->riak->send_request({ |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
93
|
|
|
|
|
|
|
method => 'PUT', |
94
|
|
|
|
|
|
|
uri => sprintf('buckets/%s/keys/%s', $self->name, $key), |
95
|
|
|
|
|
|
|
data => $value, |
96
|
|
|
|
|
|
|
links => $pack, |
97
|
|
|
|
|
|
|
(exists $opts->{'indexes'} |
98
|
|
|
|
|
|
|
? (indexes => $opts->{'indexes'}) |
99
|
|
|
|
|
|
|
: ()), |
100
|
|
|
|
|
|
|
(exists $opts->{'content_type'} |
101
|
|
|
|
|
|
|
? (content_type => $opts->{'content_type'}) |
102
|
|
|
|
|
|
|
: ()), |
103
|
|
|
|
|
|
|
(exists $opts->{'query'} |
104
|
|
|
|
|
|
|
? (query => $opts->{'query'}) |
105
|
|
|
|
|
|
|
: ()), |
106
|
|
|
|
|
|
|
}); |
107
|
|
|
|
|
|
|
|
108
|
0
|
0
|
|
|
|
|
return $resultset->first if $resultset; |
109
|
0
|
|
|
|
|
|
return; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=head2 remove ($key, $opts) |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
This will remove a key C<$key> from the bucket. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub remove { |
119
|
0
|
|
|
0
|
1
|
|
my ($self, $key, $opts) = @_; |
120
|
|
|
|
|
|
|
|
121
|
0
|
|
0
|
|
|
|
$opts ||= {}; |
122
|
|
|
|
|
|
|
|
123
|
0
|
0
|
|
|
|
|
return $self->riak->send_request({ |
124
|
|
|
|
|
|
|
method => 'DELETE', |
125
|
|
|
|
|
|
|
uri => sprintf('buckets/%s/keys/%s', $self->name, $key), |
126
|
|
|
|
|
|
|
(exists $opts->{'query'} |
127
|
|
|
|
|
|
|
? (query => $opts->{'query'}) |
128
|
|
|
|
|
|
|
: ()), |
129
|
|
|
|
|
|
|
}); |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=head2 get ($key, $opts) |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
This will get a key C<$key> from the bucket, returning a L object. |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
=cut |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub get { |
140
|
0
|
|
|
0
|
1
|
|
my ($self, $key, $opts) = @_; |
141
|
|
|
|
|
|
|
|
142
|
0
|
0
|
|
|
|
|
die("This method requires a key") unless($key); |
143
|
|
|
|
|
|
|
|
144
|
0
|
|
0
|
|
|
|
$opts ||= {}; |
145
|
|
|
|
|
|
|
|
146
|
0
|
0
|
0
|
|
|
|
confess "This method does not support multipart/mixed responses" |
147
|
|
|
|
|
|
|
if exists $opts->{'accept'} && $opts->{'accept'} eq 'multipart/mixed'; |
148
|
|
|
|
|
|
|
|
149
|
0
|
0
|
|
|
|
|
return $self->riak->send_request({ |
|
|
0
|
|
|
|
|
|
150
|
|
|
|
|
|
|
method => 'GET', |
151
|
|
|
|
|
|
|
uri => sprintf('buckets/%s/keys/%s', $self->name, $key), |
152
|
|
|
|
|
|
|
(exists $opts->{'accept'} |
153
|
|
|
|
|
|
|
? (accept => $opts->{'accept'}) |
154
|
|
|
|
|
|
|
: ()), |
155
|
|
|
|
|
|
|
(exists $opts->{'query'} |
156
|
|
|
|
|
|
|
? (query => $opts->{'query'}) |
157
|
|
|
|
|
|
|
: ()), |
158
|
|
|
|
|
|
|
})->first; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=head2 list_keys |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
List all the keys in the bucket. Warning: This is expensive, as it has to scan |
164
|
|
|
|
|
|
|
every key in the system, so don't use it unless you mean it, and know what you're |
165
|
|
|
|
|
|
|
doing. |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=cut |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub list_keys { |
171
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
172
|
|
|
|
|
|
|
|
173
|
0
|
|
|
|
|
|
my $result = $self->riak->send_request({ |
174
|
|
|
|
|
|
|
method => 'GET', |
175
|
|
|
|
|
|
|
uri => sprintf('buckets/%s/keys', $self->name), |
176
|
|
|
|
|
|
|
query => { keys => 'true' } |
177
|
|
|
|
|
|
|
})->first; |
178
|
|
|
|
|
|
|
|
179
|
0
|
|
|
|
|
|
return decode_json( $result->value )->{'keys'}; |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head2 count |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Count all the keys in a bucket. This uses MapReduce to figure out the answer, so |
185
|
|
|
|
|
|
|
it's expensive; Riak does not keep metadata on buckets for reasons that are beyond |
186
|
|
|
|
|
|
|
the scope of this module (but are well documented, so if you are interested, read up). |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=cut |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub count { |
191
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
192
|
0
|
|
|
|
|
|
my $map_reduce = Data::Riak::Fast::MapReduce->new({ |
193
|
|
|
|
|
|
|
riak => $self->riak, |
194
|
|
|
|
|
|
|
inputs => $self->name, |
195
|
|
|
|
|
|
|
phases => [ |
196
|
|
|
|
|
|
|
Data::Riak::Fast::Util::MapCount->new, |
197
|
|
|
|
|
|
|
Data::Riak::Fast::Util::ReduceCount->new |
198
|
|
|
|
|
|
|
] |
199
|
|
|
|
|
|
|
}); |
200
|
0
|
|
|
|
|
|
my $map_reduce_results = $map_reduce->mapreduce; |
201
|
0
|
|
|
|
|
|
my ( $result ) = $map_reduce_results->results->[0]; |
202
|
0
|
|
0
|
|
|
|
my ( $count ) = decode_json($result->value) || 0; |
203
|
0
|
|
|
|
|
|
return $count->[0]; |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=head2 remove_all |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
Remove all the keys from a bucket. This involves a list_keys call, so it will be |
209
|
|
|
|
|
|
|
slow on larger systems. |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=cut |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub remove_all { |
214
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
215
|
0
|
|
|
|
|
|
my $keys = $self->list_keys; |
216
|
0
|
0
|
0
|
|
|
|
return unless ref $keys eq 'ARRAY' && @$keys; |
217
|
0
|
|
|
|
|
|
foreach my $key ( @$keys ) { |
218
|
0
|
|
|
|
|
|
$self->remove( $key ); |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
sub create_link { |
223
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
224
|
0
|
0
|
|
|
|
|
my %opts = ref $_[0] eq 'HASH' ? %{$_[0]} : @_; |
|
0
|
|
|
|
|
|
|
225
|
0
|
0
|
|
|
|
|
confess "You must provide a key for a link" unless exists $opts{key}; |
226
|
0
|
0
|
|
|
|
|
confess "You must provide a riaktag for a link" unless exists $opts{riaktag}; |
227
|
0
|
0
|
|
|
|
|
return Data::Riak::Fast::Link->new({ |
228
|
|
|
|
|
|
|
bucket => $self->name, |
229
|
|
|
|
|
|
|
key => $opts{key}, |
230
|
|
|
|
|
|
|
riaktag => $opts{riaktag}, |
231
|
|
|
|
|
|
|
(exists $opts{params} ? (params => $opts{params}) : ()) |
232
|
|
|
|
|
|
|
}); |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
sub linkwalk { |
236
|
0
|
|
|
0
|
0
|
|
my ($self, $object, $params) = @_; |
237
|
0
|
0
|
|
|
|
|
return unless $params; |
238
|
0
|
|
|
|
|
|
return $self->riak->linkwalk({ |
239
|
|
|
|
|
|
|
bucket => $self->name, |
240
|
|
|
|
|
|
|
object => $object, |
241
|
|
|
|
|
|
|
params => $params |
242
|
|
|
|
|
|
|
}); |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head2 search_index |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Searches a Secondary Index to find results. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=cut |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub search_index { |
252
|
0
|
|
|
0
|
1
|
|
my ($self, $opts) = @_; |
253
|
0
|
|
0
|
|
|
|
my $field = $opts->{'field'} || die 'You must specify a field for searching Secondary indexes'; |
254
|
0
|
|
0
|
|
|
|
my $values = $opts->{'values'} || die 'You must specify values for searching Secondary indexes'; |
255
|
|
|
|
|
|
|
|
256
|
0
|
|
|
|
|
|
my $inputs = { bucket => $self->name, index => $field }; |
257
|
0
|
0
|
|
|
|
|
if(ref($values) eq 'ARRAY') { |
258
|
0
|
|
|
|
|
|
$inputs->{'start'} = $values->[0]; |
259
|
0
|
|
|
|
|
|
$inputs->{'end'} = $values->[1]; |
260
|
|
|
|
|
|
|
} else { |
261
|
0
|
|
|
|
|
|
$inputs->{'key'} = $values; |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
0
|
|
|
|
|
|
my $search_mr = Data::Riak::Fast::MapReduce->new({ |
265
|
|
|
|
|
|
|
riak => $self->riak, |
266
|
|
|
|
|
|
|
inputs => $inputs, |
267
|
|
|
|
|
|
|
phases => [ |
268
|
|
|
|
|
|
|
Data::Riak::Fast::MapReduce::Phase::Reduce->new({ |
269
|
|
|
|
|
|
|
language => 'erlang', |
270
|
|
|
|
|
|
|
module => 'riak_kv_mapreduce', |
271
|
|
|
|
|
|
|
function => 'reduce_identity', |
272
|
|
|
|
|
|
|
keep => 1 |
273
|
|
|
|
|
|
|
}) |
274
|
|
|
|
|
|
|
] |
275
|
|
|
|
|
|
|
}); |
276
|
0
|
|
|
|
|
|
return $search_mr->mapreduce->results->[0]->value; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# returns JUST the list of keys. human readable, not designed for MapReduce inputs. |
280
|
|
|
|
|
|
|
sub pretty_search_index { |
281
|
0
|
|
|
0
|
0
|
|
my ($self, $opts) = @_; |
282
|
0
|
|
|
|
|
|
return [ sort map { $_->[1] } @{decode_json($self->search_index($opts))} ]; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
sub props { |
286
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
287
|
|
|
|
|
|
|
|
288
|
0
|
|
|
|
|
|
my $result = $self->riak->send_request({ |
289
|
|
|
|
|
|
|
method => 'GET', |
290
|
|
|
|
|
|
|
uri => sprintf('buckets/%s/props', $self->name) |
291
|
|
|
|
|
|
|
})->first; |
292
|
|
|
|
|
|
|
|
293
|
0
|
|
|
|
|
|
return decode_json( $result->value )->{'props'}; |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
sub indexing { |
297
|
0
|
|
|
0
|
0
|
|
my ($self, $enable) = @_; |
298
|
|
|
|
|
|
|
|
299
|
0
|
|
|
|
|
|
my $data; |
300
|
|
|
|
|
|
|
|
301
|
0
|
0
|
|
|
|
|
if($enable) { |
302
|
0
|
|
|
|
|
|
$data->{props}->{precommit}->{mod} = 'riak_search_kv_hook'; |
303
|
0
|
|
|
|
|
|
$data->{props}->{precommit}->{fun} = 'precommit'; |
304
|
|
|
|
|
|
|
} else { |
305
|
0
|
|
|
|
|
|
$data->{props}->{precommit}->{mod} = undef; |
306
|
0
|
|
|
|
|
|
$data->{props}->{precommit}->{fun} = undef; |
307
|
|
|
|
|
|
|
}; |
308
|
|
|
|
|
|
|
|
309
|
0
|
|
|
|
|
|
return $self->riak->send_request({ |
310
|
|
|
|
|
|
|
method => 'PUT', |
311
|
|
|
|
|
|
|
content_type => 'application/json', |
312
|
|
|
|
|
|
|
uri => $self->name, |
313
|
|
|
|
|
|
|
data => encode_json($data) |
314
|
|
|
|
|
|
|
}); |
315
|
|
|
|
|
|
|
} |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=head2 create_alias ($opts) |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Creates an alias for a record using links. Helpful if your primary ID is a UUID or |
320
|
|
|
|
|
|
|
some other automatically generated identifier. Can cross buckets, as well. |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
$bucket->create_alias({ key => '123456', as => 'foo' }); |
323
|
|
|
|
|
|
|
$bucket->create_alias({ key => '123456', as => 'foo', in => $other_bucket }); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=cut |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
sub create_alias { |
328
|
0
|
|
|
0
|
1
|
|
my ($self, $opts) = @_; |
329
|
0
|
|
0
|
|
|
|
my $bucket = $opts->{in} || $self; |
330
|
0
|
|
|
|
|
|
$bucket->add($opts->{as}, $opts->{key}, { links => [ Data::Riak::Fast::Link->new( bucket => $bucket->name, riaktag => 'perl-data-riak-alias', key => $opts->{key} )] }); |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head2 resolve_alias ($alias) |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
Returns the L that $alias points to. |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=cut |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
sub resolve_alias { |
340
|
0
|
|
|
0
|
1
|
|
my ($self, $alias) = @_; |
341
|
0
|
|
|
|
|
|
return $self->linkwalk($alias, [[ 'perl-data-riak-alias', '_' ]])->first; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
345
|
22
|
|
|
22
|
|
167
|
no Mouse; |
|
22
|
|
|
|
|
50
|
|
|
22
|
|
|
|
|
182
|
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
1; |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
__END__ |