line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Persevere::Client; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
42813
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
27
|
|
4
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
36
|
|
5
|
1
|
|
|
1
|
|
1099
|
use JSON; |
|
1
|
|
|
|
|
18818
|
|
|
1
|
|
|
|
|
6
|
|
6
|
1
|
|
|
1
|
|
1471
|
use LWP::UserAgent; |
|
1
|
|
|
|
|
58575
|
|
|
1
|
|
|
|
|
42
|
|
7
|
1
|
|
|
1
|
|
13
|
use HTTP::Request qw(GET HEAD POST PUT DELETE); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
25
|
|
8
|
1
|
|
|
1
|
|
6
|
use HTTP::Status; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
379
|
|
9
|
1
|
|
|
1
|
|
6
|
use HTTP::Headers; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
10
|
1
|
|
|
1
|
|
6
|
use HTTP::Response; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
19
|
|
11
|
1
|
|
|
1
|
|
1132
|
use HTTP::Cookies; |
|
1
|
|
|
|
|
15626
|
|
|
1
|
|
|
|
|
64
|
|
12
|
1
|
|
|
1
|
|
841
|
use Persevere::Client::Class; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
54
|
|
13
|
1
|
|
|
1
|
|
12
|
use Carp qw(confess carp); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
183
|
|
14
|
1
|
|
|
1
|
|
1691
|
use Encode qw(encode); |
|
1
|
|
|
|
|
16705
|
|
|
1
|
|
|
|
|
1627
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
Persevere::Client - A Simple to use Interface to Persevere the JSON Database |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 VERSION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Version 0.31 |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=cut |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
our $VERSION = '0.31'; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub new{ |
29
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
30
|
0
|
0
|
|
|
|
|
my %opt = @_ == 1 ? %{$_[0]} : @_; |
|
0
|
|
|
|
|
|
|
31
|
0
|
|
|
|
|
|
my %self; |
32
|
0
|
|
|
|
|
|
$self{module_version} = $VERSION; |
33
|
0
|
0
|
|
|
|
|
if ($opt{uri}){ |
34
|
0
|
|
|
|
|
|
$self{uri} = $opt{uri}; |
35
|
0
|
0
|
|
|
|
|
$self{uri} .= '/' unless $self{uri} =~ m{/$}; |
36
|
|
|
|
|
|
|
}else{ |
37
|
0
|
|
0
|
|
|
|
$self{uri} = ($opt{scheme} || 'http') . '://' . |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
38
|
|
|
|
|
|
|
($opt{host} || 'localhost') . ':' . |
39
|
|
|
|
|
|
|
($opt{port} || '8080') . '/'; |
40
|
|
|
|
|
|
|
} |
41
|
0
|
|
0
|
|
|
|
$self{json} = ($opt{json} || JSON->new->utf8->allow_blessed); |
42
|
0
|
|
0
|
|
|
|
$self{ua} = ($opt{ua} || LWP::UserAgent->new(agent => ($self{agent} || "Persevere::Client/$VERSION"))); |
43
|
0
|
0
|
|
|
|
|
if (defined $opt{query_timeout}){ |
44
|
0
|
|
|
|
|
|
$self{query_timeout} = $opt{query_timeout}; |
45
|
|
|
|
|
|
|
}else{ |
46
|
0
|
|
|
|
|
|
$self{query_timeout} = 30; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
# Throw this in an eval so other ua's don't croak here? |
49
|
0
|
|
|
|
|
|
$self{ua}->timeout($self{query_timeout}); |
50
|
0
|
0
|
|
|
|
|
if (defined $opt{defaultSourceClass}){ |
51
|
0
|
|
|
|
|
|
$self{defaultSourceClass} = $opt{defaultSourceClass}; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
0
|
|
0
|
|
|
|
$self{auth_type} = ($opt{auth_type} || "basic"); |
55
|
0
|
0
|
0
|
|
|
|
if (!( ($self{auth_type} eq "json-rpc") || ($self{auth_type} eq "basic") || ($self{auth_type} eq "none") )){ |
|
|
0
|
|
|
|
|
|
56
|
0
|
|
|
|
|
|
confess "Invalid auth type. Choices are json-rpc, basic, or none"; |
57
|
|
|
|
|
|
|
}elsif (!($self{auth_type} eq "none")){ |
58
|
0
|
|
0
|
|
|
|
$self{username} = $opt{username} || confess "A username must be provided if auth_type is not set to none"; |
59
|
0
|
|
0
|
|
|
|
$self{password} = $opt{password} || confess "A password must be provided if auth_type is not set to none"; |
60
|
0
|
0
|
|
|
|
|
if ($self{auth_type} eq "json-rpc"){ |
|
|
0
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# Not Implemented yet |
62
|
|
|
|
|
|
|
# $self{ua}->cookie_jar(HTTP::Cookies->new); |
63
|
|
|
|
|
|
|
# my $auth_string = '{"method":"authenticate", "params":[ "' . $self{username} . '":"' . $self{password} . '"], "id":"call0"}'; |
64
|
|
|
|
|
|
|
# my $authin = $self{ua}->(HTTP::Request->new(POST, $self{uri} . "/Class/User", undef, $auth_string )); |
65
|
|
|
|
|
|
|
# my $authin = $self{req}->('POST', $self{uri} . "/Class/User", undef, $auth_string); |
66
|
|
|
|
|
|
|
# print $authin->{status_line} . "\n"; |
67
|
|
|
|
|
|
|
}elsif ($self{auth_type} eq "basic"){ |
68
|
0
|
|
|
|
|
|
$self{ua}->default_headers->authorization_basic($self{username}, $self{password}); |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
0
|
|
|
|
|
|
$self{ua}->default_headers->push_header('Accept' => "application/json"); |
73
|
|
|
|
|
|
|
|
74
|
0
|
0
|
|
|
|
|
if (defined $opt{debug}){ |
75
|
0
|
|
|
|
|
|
$self{debug} = $opt{debug}; |
76
|
|
|
|
|
|
|
}else{ |
77
|
0
|
|
|
|
|
|
$self{debug} = 0; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
0
|
0
|
|
|
|
|
if (defined $opt{showwarnings}){ |
81
|
0
|
|
|
|
|
|
$self{showwarnings} = $opt{showwarnings}; |
82
|
|
|
|
|
|
|
}else{ |
83
|
0
|
|
|
|
|
|
$self{showwarnings} = 1; |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
0
|
0
|
|
|
|
|
if (defined $opt{exist_is_error}){ |
87
|
0
|
|
|
|
|
|
$self{exist_is_error} = $opt{exist_is_error}; |
88
|
|
|
|
|
|
|
}else{ |
89
|
0
|
|
|
|
|
|
$self{exist_is_error} = 0; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
return bless \%self, $class; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub testConnection{ |
96
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
97
|
0
|
|
|
|
|
|
my $testpath = $self->{uri} . "status"; |
98
|
0
|
|
|
|
|
|
my $testresponse = $self->req('GET', $testpath, undef, undef, 1); |
99
|
0
|
0
|
|
|
|
|
if (!($testresponse->{success})){ |
100
|
0
|
|
|
|
|
|
return 0; |
101
|
|
|
|
|
|
|
}else{ |
102
|
0
|
|
|
|
|
|
return 1; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub serverInfo{ |
107
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
108
|
0
|
|
|
|
|
|
my $inforesponse = $self->req('GET', "$self->{uri}status", undef, undef, 1); |
109
|
0
|
0
|
|
|
|
|
if ($self->testConnection){ |
110
|
0
|
|
|
|
|
|
return $inforesponse; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub classExists{ |
115
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
116
|
0
|
|
|
|
|
|
my $ClassName = shift; |
117
|
0
|
0
|
|
|
|
|
if (!(defined $ClassName)){ |
118
|
0
|
|
|
|
|
|
$self->alert("No class passed to classExists, classExists requires a class name to properly function"); |
119
|
|
|
|
|
|
|
} |
120
|
0
|
0
|
|
|
|
|
if ($self->{debug}){ |
121
|
0
|
|
|
|
|
|
print "DEBUG (FUNCTION classExists): GET $self->{uri}Class/$ClassName\n"; |
122
|
|
|
|
|
|
|
} |
123
|
0
|
|
|
|
|
|
my $classresponse = $self->req('GET', "$self->{uri}Class/$ClassName", undef, undef, 1); |
124
|
0
|
0
|
|
|
|
|
if ($classresponse->{success}){ |
125
|
0
|
|
|
|
|
|
return 1; |
126
|
|
|
|
|
|
|
}else{ |
127
|
0
|
|
|
|
|
|
return 0; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
# ***** Warning ***** |
131
|
|
|
|
|
|
|
# this does not represent how the user interface will behave once implemented |
132
|
|
|
|
|
|
|
# These are just personal notes |
133
|
|
|
|
|
|
|
# ***** Warning ***** |
134
|
|
|
|
|
|
|
#sub newUser{ |
135
|
|
|
|
|
|
|
# my $self = shift; |
136
|
|
|
|
|
|
|
# my $user = shift; |
137
|
|
|
|
|
|
|
# my $pass = shift; |
138
|
|
|
|
|
|
|
# my $userresponse = $self->req('POST', "$self->{uri}Class/User", undef, |
139
|
|
|
|
|
|
|
# '{"method":"createUser","id":"register","params":["' . $user . '","' . $pass . '"]}'); |
140
|
|
|
|
|
|
|
# if ($userresponse->{code} == 204){ |
141
|
|
|
|
|
|
|
# return 0; |
142
|
|
|
|
|
|
|
# }else{ |
143
|
|
|
|
|
|
|
# if ($self->{debug}){ |
144
|
|
|
|
|
|
|
# carp $userresponse->{status_line}; |
145
|
|
|
|
|
|
|
# } |
146
|
|
|
|
|
|
|
# return 1; |
147
|
|
|
|
|
|
|
# } |
148
|
|
|
|
|
|
|
#} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub listClassNames{ |
151
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
152
|
0
|
|
|
|
|
|
my @classlist; |
153
|
0
|
|
|
|
|
|
my $classresponse = $self->req('GET', "$self->{uri}Class/"); |
154
|
0
|
0
|
|
|
|
|
if ($self->{debug}){ |
155
|
0
|
|
|
|
|
|
print "DEBUG (FUNCTION listClassNames): GET $self->{uri}Class/\n"; |
156
|
|
|
|
|
|
|
} |
157
|
0
|
|
|
|
|
|
my @allclasses = $classresponse->{data}; |
158
|
0
|
|
|
|
|
|
my @inside = @{$allclasses[0]}; |
|
0
|
|
|
|
|
|
|
159
|
0
|
|
|
|
|
|
foreach my $item (@inside){ |
160
|
0
|
0
|
|
|
|
|
if (defined $item->{core}){ |
161
|
0
|
0
|
|
|
|
|
if ($item->{core} == 1){ |
162
|
0
|
|
|
|
|
|
next; |
163
|
|
|
|
|
|
|
}else{ |
164
|
0
|
|
|
|
|
|
push @classlist, $item->{id}; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
}else{ |
167
|
0
|
|
|
|
|
|
push @classlist, $item->{id}; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
} |
170
|
0
|
|
|
|
|
|
$classresponse->{data} = \@classlist; |
171
|
0
|
|
|
|
|
|
return $classresponse; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub req{ |
175
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
176
|
0
|
|
|
|
|
|
my $meth = shift; |
177
|
0
|
|
|
|
|
|
my $path = shift; |
178
|
0
|
|
|
|
|
|
my $header = shift; |
179
|
0
|
|
|
|
|
|
my $cont = shift; |
180
|
0
|
|
|
|
|
|
my $nowarn = shift; |
181
|
0
|
|
|
|
|
|
my $noencode = shift; |
182
|
0
|
|
|
|
|
|
my $content; |
183
|
0
|
0
|
|
|
|
|
if (!(defined $nowarn)){ |
184
|
0
|
|
|
|
|
|
$nowarn = 0; |
185
|
|
|
|
|
|
|
} |
186
|
0
|
0
|
|
|
|
|
if (!(defined $noencode)){ |
187
|
0
|
|
|
|
|
|
$noencode = 0; |
188
|
|
|
|
|
|
|
} |
189
|
0
|
0
|
|
|
|
|
if ($noencode){ |
|
|
0
|
|
|
|
|
|
190
|
0
|
|
|
|
|
|
$content = $cont; |
191
|
|
|
|
|
|
|
}elsif (ref $cont){ |
192
|
0
|
|
|
|
|
|
$content = encode('utf-8', $self->{json}->encode($cont)); |
193
|
|
|
|
|
|
|
} |
194
|
0
|
|
|
|
|
|
my $dheader; # debug header |
195
|
0
|
0
|
|
|
|
|
if (!(defined $header)){ |
196
|
0
|
|
|
|
|
|
$dheader = ""; |
197
|
|
|
|
|
|
|
} |
198
|
0
|
0
|
|
|
|
|
if (!(defined $content)){ |
199
|
0
|
|
|
|
|
|
$content = ""; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
# if ($self->{debug}){ |
202
|
|
|
|
|
|
|
# print "DEBUG (FUNCTION req): Method: $meth Path: $path Header: $dheader Content: $content NoWarn: $nowarn NoEncode: $noencode\n"; |
203
|
|
|
|
|
|
|
# } |
204
|
|
|
|
|
|
|
|
205
|
0
|
|
|
|
|
|
my $res = $self->{ua}->request(HTTP::Request->new($meth, $path, $header, $content)); |
206
|
0
|
|
|
|
|
|
my $query = "$meth, $path, $dheader, $content"; |
207
|
0
|
|
|
|
|
|
my $auth_status; |
208
|
0
|
0
|
|
|
|
|
if ($res->code == 401){ |
209
|
0
|
|
|
|
|
|
$auth_status = 0; |
210
|
|
|
|
|
|
|
}else{ |
211
|
0
|
|
|
|
|
|
$auth_status = 1; |
212
|
|
|
|
|
|
|
} |
213
|
0
|
|
|
|
|
|
my $ret = { |
214
|
|
|
|
|
|
|
code => $res->code, |
215
|
|
|
|
|
|
|
status_line => $res->status_line, |
216
|
|
|
|
|
|
|
success => 0, |
217
|
|
|
|
|
|
|
content => $res->content, |
218
|
|
|
|
|
|
|
auth => $auth_status, |
219
|
|
|
|
|
|
|
query => $query |
220
|
|
|
|
|
|
|
}; |
221
|
0
|
0
|
|
|
|
|
if ($res->is_success){ |
222
|
0
|
|
|
|
|
|
$ret->{success} = 1; |
223
|
0
|
0
|
|
|
|
|
if (!($noencode)){ |
224
|
0
|
|
|
|
|
|
$ret->{data} = $self->{json}->decode($res->content); |
225
|
|
|
|
|
|
|
}else{ |
226
|
0
|
|
|
|
|
|
$ret->{data} = $res->content; |
227
|
|
|
|
|
|
|
} |
228
|
0
|
0
|
|
|
|
|
$ret->{range} = $res->header('Content-Range') if (defined $res->header('Content-Range')); |
229
|
|
|
|
|
|
|
}else{ |
230
|
0
|
0
|
|
|
|
|
if (!($nowarn)){ |
231
|
0
|
|
|
|
|
|
$self->alert($res->content); |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
} |
234
|
0
|
|
|
|
|
|
return $ret; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub alert { |
238
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
239
|
0
|
|
|
|
|
|
my @message = @_; |
240
|
0
|
0
|
|
|
|
|
if ($self->{showwarnings}){ |
241
|
0
|
|
|
|
|
|
carp @message; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
sub class{ |
246
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
247
|
0
|
|
|
|
|
|
my $ClassName = shift; |
248
|
0
|
|
|
|
|
|
return Persevere::Client::Class->new(name => $ClassName, client => $self); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head1 SYNOPSIS |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
This module Is a simple interface to Persevere, the JSON Database. |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
This module provides an interface similar to that of Couchdb::Client |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
View documentation on Persevere::Client::Class for information on how |
258
|
|
|
|
|
|
|
to interact with Persevere Classes. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
use Persevere::Client; |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
my $persvr = Persevere::Client->new( |
263
|
|
|
|
|
|
|
host => "localhost", |
264
|
|
|
|
|
|
|
port => "8080", |
265
|
|
|
|
|
|
|
auth_type => "basic", |
266
|
|
|
|
|
|
|
username => "user", |
267
|
|
|
|
|
|
|
password => "pass" |
268
|
|
|
|
|
|
|
); |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
die "Unable to connect to $persvr->{uri}\n" if !($persvr->testConnection); |
271
|
|
|
|
|
|
|
my $status; |
272
|
|
|
|
|
|
|
my $statusreq = $persvr->serverInfo; |
273
|
|
|
|
|
|
|
if ($statusreq->{success}){ |
274
|
|
|
|
|
|
|
$status = $statusreq->{data}; |
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
print "VM: $status->{vm}\nVersion: $status->{version}\n"; |
277
|
|
|
|
|
|
|
print "Class File Exists\n" if $persvr->classExists("File"); |
278
|
|
|
|
|
|
|
print "Class Garbage Doesn't Exist\n" if (!($persvr->classExists("garbage"))); |
279
|
|
|
|
|
|
|
my @class_list; |
280
|
|
|
|
|
|
|
my $classreq = $persvr->listClassNames; |
281
|
|
|
|
|
|
|
if ($classreq->{success}){ |
282
|
|
|
|
|
|
|
@class_list = @{$classreq->{data}}; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=head1 MEATHODS |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=over 8 |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=item new |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
Constructor |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
uri - Takes a hash or hashref of options: uri which specifies the server's URI; scheme, host, port which are used if uri isn't provided and default to 'http', 'localhost', and '8080' respectively; |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
json - which defaults to a JSON object with utf8 and allow_blessed turned on but can be replaced with anything with the same interface; |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
ua - which is a LWP::UserAgent object and can also be replaced. |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
agent - Replace the name the defaut LWP::UserAgent reports to the db when it crud's |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
debug - boolean, defaults to false, set to 1 to enable debug messages (show's crud sent to persevere). |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
auth_type - can be set to basic, json-rpc, or none, basic is default, and throws an error without a username and password. json-rpc auth is not yet implemented. |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
query_timeout - how long to wait until timing out on a request, defaults to 30. |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
exist_is_error - return an error if a class we try and create already exists |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
showwarnings - carp warning messages |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=item testConnection |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
Returns true if a connection can be made to the server, false otherwise. |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=item req |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
All requests made to the server that do not have a boolean response return a req hash. |
318
|
|
|
|
|
|
|
All req hashes contain: |
319
|
|
|
|
|
|
|
code - http status code |
320
|
|
|
|
|
|
|
status_line - http status_line (this is what you use to debug why a request failed) |
321
|
|
|
|
|
|
|
success - false for failure, true for success |
322
|
|
|
|
|
|
|
content - content of the request |
323
|
|
|
|
|
|
|
auth - false if authentication failed for the query, true if authentication succeeded |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
Successful requests contain: |
326
|
|
|
|
|
|
|
data - decoded json data, when assigning this to a variable its type must be declared. most data will be arrays, with the exception of status. |
327
|
|
|
|
|
|
|
Example: |
328
|
|
|
|
|
|
|
my $postreq = $initialclass->createObjects(\@post_data); |
329
|
|
|
|
|
|
|
if ($postreq->{success}){ |
330
|
|
|
|
|
|
|
foreach (@{$postreq->{data}}){ |
331
|
|
|
|
|
|
|
print "$_\n"; |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
}else{ |
334
|
|
|
|
|
|
|
warn "unable to post data"; |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
range - if applicable returns the range header information for the request. |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
using req hashes provides a uniform approach to dealing with error handling for auth, and failed requests. |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=item serverInfo |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
Returns a req hash, server metadata is contained in {data}, and is typically something that looks like { id => "status", version => "1.0 beta 2" ... }. It throws an warning if it can't connect. |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=item classExists |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Returns true if a class of that name exists, false otherwise. |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=item listClassNames |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
Returns an req hash, with {data} containing all non core class names that the server knows of. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=item class |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
Returns a new Persevere::Client::Class object for a class of that name. Note that the Class does not need to exist yet, and will not be created if it doesn't. The create method will create the class, and is documented in Persevere::Client::Class |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=back |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=head1 AUTHOR |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
Nathanael Anderson, C<< >> |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=head1 BUGS |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
366
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
367
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
=head1 SUPPORT |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
perldoc Persevere::Client |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
You can also look for information at: |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
=over 4 |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
L |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
L |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=item * CPAN Ratings |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
L |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=item * Search CPAN |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
L |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=back |
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Thanks to mst in #perl-help on irc.perl.org for looking over the code, and providing feedback |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
Copyright 2009-2011 Nathanael Anderson. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
408
|
|
|
|
|
|
|
under the same terms as Perl itself. |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=cut |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
1; # End of Persevere::Client |