line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# Web::DataService::Request |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# A base class that implements a data service for the PaleoDB. This can be |
5
|
|
|
|
|
|
|
# subclassed to produce any necessary data service. For examples, see |
6
|
|
|
|
|
|
|
# TaxonQuery.pm and CollectionQuery.pm. |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# Author: Michael McClennen |
9
|
|
|
|
|
|
|
|
10
|
2
|
|
|
2
|
|
16
|
use strict; |
|
2
|
|
|
|
|
18
|
|
|
2
|
|
|
|
|
81
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
package Web::DataService::Request; |
13
|
|
|
|
|
|
|
|
14
|
2
|
|
|
2
|
|
15
|
use Carp 'croak'; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
88
|
|
15
|
|
|
|
|
|
|
|
16
|
2
|
|
|
2
|
|
1233
|
use Moo; |
|
2
|
|
|
|
|
5422
|
|
|
2
|
|
|
|
|
11
|
|
17
|
2
|
|
|
2
|
|
3830
|
use namespace::clean; |
|
2
|
|
|
|
|
19448
|
|
|
2
|
|
|
|
|
12
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# The required attribute 'ds' is the data service with which this request is |
21
|
|
|
|
|
|
|
# associated. |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
has ds => ( is => 'ro', isa => \&is_dataservice_object, required => 1 ); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# The required attribute 'outer' is the request object generated by the |
26
|
|
|
|
|
|
|
# foundation framework. |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
has outer => ( is => 'ro', required => 1 ); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# The attribute 'path' selects the data service node which will be used to |
31
|
|
|
|
|
|
|
# process the request. If not given explicitly, it will be retrieved from the |
32
|
|
|
|
|
|
|
# 'outer' request object. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
has path => ( is => 'rw', trigger => \&_match_node ); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# The following argument can be specified separately, or you can let it be |
37
|
|
|
|
|
|
|
# extracted from the value of 'path'. But note that if 'path' does not |
38
|
|
|
|
|
|
|
# correspond to a defined node, then 'rest_path' will be modified |
39
|
|
|
|
|
|
|
# accordingly. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
has rest_path => ( is => 'ro' ); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# The attribute 'http_method' selects the HTTP method which will be used to |
44
|
|
|
|
|
|
|
# process the request. If not given explicitly, it will be retrieved from the |
45
|
|
|
|
|
|
|
# 'outer' request object. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
has http_method => ( is => 'rw' ); |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
# The following attributes will be determined automatically by |
50
|
|
|
|
|
|
|
# Web::DataService, unless explicitly defined at initialization time or |
51
|
|
|
|
|
|
|
# explicitly overridden later. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
has is_invalid_request => ( is => 'rw' ); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
has is_doc_request => ( is => 'rw' ); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
has output_format => ( is => 'rw' ); |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
has output_vocab => ( is => 'rw' ); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
has output_linebreak => ( is => 'rw' ); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
has result_limit => ( is => 'rw' ); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
has result_offset => ( is => 'rw' ); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
has display_header => ( is => 'rw' ); #, lazy => 1, builder => sub { $_[0]->_init_value('header') } ); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
has display_datainfo => ( is => 'rw' ); |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
has display_counts => ( is => 'rw' ); |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
has save_output => ( is => 'rw' ); |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
has save_filename => ( is => 'rw' ); |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
has do_not_stream => ( is => 'rw' ); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# The following attributes will be determined automatically by |
80
|
|
|
|
|
|
|
# Web::DataService and should not be overridden. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
has node_path => ( is => 'ro', init_arg => '_node_path' ); |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
has is_node_path => ( is => 'ro', init_arg => undef ); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# BUILD ( ) |
88
|
|
|
|
|
|
|
# |
89
|
|
|
|
|
|
|
# Finish generating a new request object. This involves determining the "node |
90
|
|
|
|
|
|
|
# path" from the "raw path" that was specified when this object was |
91
|
|
|
|
|
|
|
# initialized. Depending upon the features enabled for this data service, the |
92
|
|
|
|
|
|
|
# path may be processed in different ways. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub BUILD { |
95
|
|
|
|
|
|
|
|
96
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
97
|
|
|
|
|
|
|
|
98
|
0
|
|
|
|
|
|
my $ds = $self->{ds}; |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
sub is_dataservice_object { |
103
|
|
|
|
|
|
|
|
104
|
0
|
0
|
0
|
0
|
0
|
|
die "must be an object of class Web::DataService" |
105
|
|
|
|
|
|
|
unless ref $_[0] && $_[0]->isa('Web::DataService'); |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub _init_value { |
110
|
|
|
|
|
|
|
|
111
|
0
|
|
|
0
|
|
|
my ($self, $attr) = @_; |
112
|
|
|
|
|
|
|
|
113
|
0
|
0
|
|
|
|
|
if ( my $special = $self->special_value($attr) ) |
|
|
0
|
|
|
|
|
|
114
|
|
|
|
|
|
|
{ |
115
|
0
|
|
|
|
|
|
return $special; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
elsif ( my $default = $self->{ds}->node_attr("default_$attr") ) |
119
|
|
|
|
|
|
|
{ |
120
|
0
|
|
|
|
|
|
return $default; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
else |
124
|
|
|
|
|
|
|
{ |
125
|
0
|
|
|
|
|
|
return; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# _match_node ( ) |
131
|
|
|
|
|
|
|
# |
132
|
|
|
|
|
|
|
# This routine will be called whenever the 'path' attribute of this request is |
133
|
|
|
|
|
|
|
# set. It determines the closest matching 'node_path' and sets some other |
134
|
|
|
|
|
|
|
# attributes. |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub _match_node { |
137
|
|
|
|
|
|
|
|
138
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
139
|
|
|
|
|
|
|
|
140
|
0
|
|
|
|
|
|
local($Carp::CarpLevel) = 1; # We shouldn't have to do this, but |
141
|
|
|
|
|
|
|
# Moo and Carp don't play well together. |
142
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
my $ds = $self->{ds}; |
144
|
0
|
|
|
|
|
|
my $raw_path = $self->{path}; |
145
|
0
|
|
|
|
|
|
my $suffix_is_missing; |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# We start with the raw path and trim it in various ways to find the |
148
|
|
|
|
|
|
|
# closest matching data service node. |
149
|
|
|
|
|
|
|
|
150
|
0
|
|
|
|
|
|
my $node_path = $raw_path; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
# If the raw path exactly matches any node, we just use that. Otherwise, |
153
|
|
|
|
|
|
|
# apply any applicable path transformations. |
154
|
|
|
|
|
|
|
|
155
|
0
|
0
|
|
|
|
|
if ( exists $ds->{node_attrs}{$raw_path} ) |
156
|
|
|
|
|
|
|
{ |
157
|
0
|
|
|
|
|
|
$self->{is_node_path} = 1; |
158
|
0
|
0
|
|
|
|
|
$self->{is_doc_request} = 1 if $ds->has_feature('format_suffix'); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
else |
162
|
|
|
|
|
|
|
{ |
163
|
|
|
|
|
|
|
# If the feature 'format_suffix' is enabled and the specified path has |
164
|
|
|
|
|
|
|
# a suffix, split it off. |
165
|
|
|
|
|
|
|
|
166
|
0
|
0
|
|
|
|
|
if ( $ds->has_feature('format_suffix') ) |
167
|
|
|
|
|
|
|
{ |
168
|
0
|
0
|
|
|
|
|
if ( $node_path =~ qr{ ^ (.+) [.] (.+) }xs ) |
169
|
|
|
|
|
|
|
{ |
170
|
0
|
|
|
|
|
|
$node_path = $1; |
171
|
0
|
|
|
|
|
|
$self->output_format($2); |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
else |
175
|
|
|
|
|
|
|
{ |
176
|
0
|
|
|
|
|
|
$suffix_is_missing = 1; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# If the feature 'doc_paths' is enabled and the specified path ends in |
181
|
|
|
|
|
|
|
# '_doc', remove that string and set the 'is_doc_request' flag for this |
182
|
|
|
|
|
|
|
# request. Under this feature, the path "abc/def_doc" indicates a |
183
|
|
|
|
|
|
|
# request for doumentation about the path "abc/def". |
184
|
|
|
|
|
|
|
|
185
|
0
|
0
|
|
|
|
|
if ( $ds->has_feature('doc_paths') ) |
|
|
0
|
|
|
|
|
|
186
|
|
|
|
|
|
|
{ |
187
|
0
|
0
|
0
|
|
|
|
if ( $node_path eq '' ) |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
188
|
|
|
|
|
|
|
{ |
189
|
0
|
|
|
|
|
|
$self->{is_doc_request} = 1; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
elsif ( ref $ds->{doc_path_regex} eq 'Regexp' && $node_path =~ $ds->{doc_path_regex} ) |
193
|
|
|
|
|
|
|
{ |
194
|
0
|
|
|
|
|
|
$node_path = $1; |
195
|
0
|
|
|
|
|
|
$self->{is_doc_request} = 1; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
elsif ( $ds->{doc_index} && $node_path eq $ds->{doc_index} ) |
199
|
|
|
|
|
|
|
{ |
200
|
0
|
|
|
|
|
|
$node_path = ''; |
201
|
0
|
|
|
|
|
|
$self->{is_doc_request} = 1; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
elsif ( $suffix_is_missing ) |
205
|
|
|
|
|
|
|
{ |
206
|
0
|
|
|
|
|
|
$self->{is_doc_request} = 1; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# Otherwise, if the special parameter 'document' is enabled and |
211
|
|
|
|
|
|
|
# present then set the 'is_doc_request' flag for this request. |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
elsif ( my $document_param = $ds->special_param('document') ) |
214
|
|
|
|
|
|
|
{ |
215
|
0
|
|
|
|
|
|
my $params = $Web::DataService::FOUNDATION->get_params($self->{outer}); |
216
|
|
|
|
|
|
|
|
217
|
0
|
0
|
|
|
|
|
$self->{is_doc_request} = 1 if defined $params->{$document_param}; |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# We then lop off components as necessary until we get to a node that has |
221
|
|
|
|
|
|
|
# attributes or until we reach the empty string. We set the 'is_node_path' |
222
|
|
|
|
|
|
|
# flag to 0 (unless it has already been set) to indicate that the request |
223
|
|
|
|
|
|
|
# path does not fully match a defined node. |
224
|
|
|
|
|
|
|
|
225
|
0
|
|
|
|
|
|
while ( $node_path ne '' ) |
226
|
|
|
|
|
|
|
{ |
227
|
|
|
|
|
|
|
# If we find a node with attributes, stop here. |
228
|
|
|
|
|
|
|
|
229
|
0
|
0
|
|
|
|
|
last if exists $ds->{node_attrs}{$node_path}; |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# If this is a documentation request and a template exists that |
232
|
|
|
|
|
|
|
# would correspond to the current node path, then create the node |
233
|
|
|
|
|
|
|
# and stop here. |
234
|
|
|
|
|
|
|
|
235
|
0
|
0
|
0
|
|
|
|
if ( $self->{is_doc_request} and my $doc_path = $ds->check_for_template($node_path) ) |
236
|
|
|
|
|
|
|
{ |
237
|
0
|
|
|
|
|
|
$ds->make_doc_node($node_path, $doc_path); |
238
|
0
|
|
|
|
|
|
last; |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Otherwise, lop off the last path component and try again. |
242
|
|
|
|
|
|
|
|
243
|
0
|
|
0
|
|
|
|
$self->{is_node_path} //= 0; |
244
|
|
|
|
|
|
|
|
245
|
0
|
0
|
|
|
|
|
if ( $node_path =~ qr{ ^ (.*) / (.*) }xs ) |
246
|
|
|
|
|
|
|
{ |
247
|
0
|
|
|
|
|
|
$node_path = $1; |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
else |
251
|
|
|
|
|
|
|
{ |
252
|
0
|
|
|
|
|
|
$node_path = ''; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
# An empty path should always produce documentation. In fact, it should |
258
|
|
|
|
|
|
|
# produce a "main documentation page" for this data service. The data |
259
|
|
|
|
|
|
|
# service author should make sure that this is so. |
260
|
|
|
|
|
|
|
|
261
|
0
|
0
|
|
|
|
|
if ( $node_path eq '' ) |
|
|
0
|
|
|
|
|
|
262
|
|
|
|
|
|
|
{ |
263
|
0
|
|
|
|
|
|
$self->{is_doc_request} = 1; |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# If the selected node is disabled, set the 'is_invalid_request' attribute. |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
elsif ( $ds->node_attr($node_path, 'disabled') ) |
269
|
|
|
|
|
|
|
{ |
270
|
0
|
|
|
|
|
|
$self->{is_invalid_request} = 1; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# If 'is_node_path' has not yet been set, then we assume it should be 1. |
274
|
|
|
|
|
|
|
|
275
|
0
|
|
0
|
|
|
|
$self->{is_node_path} //= 1; |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
# We save all of the characters removed from the raw path as $rest_path, |
278
|
|
|
|
|
|
|
# so that (for example) we can send a requested file. |
279
|
|
|
|
|
|
|
|
280
|
0
|
|
|
|
|
|
$self->{rest_path} = substr($raw_path, length($node_path)); |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
# If we got an empty path, turn it into the root node path '/'. |
283
|
|
|
|
|
|
|
|
284
|
0
|
0
|
|
|
|
|
$self->{node_path} = $node_path eq '' ? '/' : $node_path; |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# If the node that we got has either the 'file_path' or 'file_dir' |
287
|
|
|
|
|
|
|
# attribute, then mark this request as 'is_file_path'. If it has |
288
|
|
|
|
|
|
|
# 'file_path', then it is invalid unless $rest_path is empty. If it has |
289
|
|
|
|
|
|
|
# 'file_dir', then it is invalid unless $rest_path is NOT empty. |
290
|
|
|
|
|
|
|
|
291
|
0
|
0
|
|
|
|
|
if ( $ds->node_attr($self->{node_path}, 'file_dir') ) |
|
|
0
|
|
|
|
|
|
292
|
|
|
|
|
|
|
{ |
293
|
0
|
|
|
|
|
|
$self->{is_file_path} = 1; |
294
|
|
|
|
|
|
|
$self->{is_invalid_request} = 1 unless defined $self->{rest_path} && |
295
|
0
|
0
|
0
|
|
|
|
$self->{rest_path} ne ''; |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
elsif ( $ds->node_attr($self->{node_path}, 'file_path' ) ) |
299
|
|
|
|
|
|
|
{ |
300
|
0
|
|
|
|
|
|
$self->{is_file_path} = 1; |
301
|
|
|
|
|
|
|
$self->{is_invalid_request} = 1 if defined $self->{rest_path} && |
302
|
0
|
0
|
0
|
|
|
|
$self->{rest_path} ne ''; |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
# execute ( ) |
308
|
|
|
|
|
|
|
# |
309
|
|
|
|
|
|
|
# Execute this request, and return the result. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub execute { |
312
|
|
|
|
|
|
|
|
313
|
0
|
|
|
0
|
1
|
|
return $_[0]->{ds}->execute_request($_[0]->{outer}); |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
# configure ( ) |
318
|
|
|
|
|
|
|
# |
319
|
|
|
|
|
|
|
# Configure this request for execution. |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub configure { |
322
|
|
|
|
|
|
|
|
323
|
0
|
|
|
0
|
0
|
|
return $_[0]->{ds}->configure_request($_[0]->{outer}); |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
# Common methods needed for both execution and documentation |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
# request_url |
330
|
|
|
|
|
|
|
# |
331
|
|
|
|
|
|
|
# Return the raw (unparsed) request URL |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
sub request_url { |
334
|
|
|
|
|
|
|
|
335
|
0
|
|
|
0
|
1
|
|
return $Web::DataService::FOUNDATION->get_request_url($_[0]->{outer}); |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
# base_url |
340
|
|
|
|
|
|
|
# |
341
|
|
|
|
|
|
|
# Return the base component of the URL for this request, of the form "http://some.host/". |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
sub base_url { |
344
|
|
|
|
|
|
|
|
345
|
0
|
|
|
0
|
1
|
|
return $Web::DataService::FOUNDATION->get_base_url($_[0]->{outer}); |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
# root_url ( ) |
350
|
|
|
|
|
|
|
# |
351
|
|
|
|
|
|
|
# Return the base url plus the path prefix. |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
sub root_url { |
354
|
|
|
|
|
|
|
|
355
|
0
|
|
|
0
|
1
|
|
return $Web::DataService::FOUNDATION->get_base_url($_[0]) . $_[0]->{ds}{path_prefix}; |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# path_prefix ( ) |
360
|
|
|
|
|
|
|
# |
361
|
|
|
|
|
|
|
# Return the path prefix for this request. |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
sub path_prefix { |
364
|
|
|
|
|
|
|
|
365
|
0
|
|
|
0
|
1
|
|
return $_[0]->{ds}{path_prefix}; |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# generate_url ( attrs ) |
370
|
|
|
|
|
|
|
# |
371
|
|
|
|
|
|
|
# Generate a URL based on the specified attributes. This routine calls |
372
|
|
|
|
|
|
|
# Web::DataService::generate_url to create a site-relative URL, then applies |
373
|
|
|
|
|
|
|
# the base URL from the current request if asked to do so. |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
sub generate_url { |
376
|
|
|
|
|
|
|
|
377
|
0
|
|
|
0
|
1
|
|
my ($self, $attrs) = @_; |
378
|
|
|
|
|
|
|
|
379
|
0
|
|
|
|
|
|
return $self->{ds}->generate_site_url($attrs); |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
# data_info ( ) |
384
|
|
|
|
|
|
|
# |
385
|
|
|
|
|
|
|
# Return a hash of information about the request. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
sub data_info { |
388
|
|
|
|
|
|
|
|
389
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
# We start with the information provided by the data service, and add some |
392
|
|
|
|
|
|
|
# info specific to this request. |
393
|
|
|
|
|
|
|
|
394
|
0
|
|
|
|
|
|
my $ds = $self->{ds}; |
395
|
0
|
|
|
|
|
|
my $info = $ds->data_info; |
396
|
|
|
|
|
|
|
|
397
|
0
|
|
|
|
|
|
my $node_path = $self->node_path; |
398
|
0
|
|
|
|
|
|
my $base_url = $self->base_url; |
399
|
|
|
|
|
|
|
|
400
|
0
|
|
|
|
|
|
my $doc_url = $self->generate_url({ node => $node_path }); |
401
|
0
|
|
|
|
|
|
$doc_url =~ s{^/}{}; |
402
|
0
|
|
|
|
|
|
my $data_url = $self->request_url; |
403
|
0
|
|
|
|
|
|
$data_url =~ s{^/}{}; |
404
|
|
|
|
|
|
|
|
405
|
0
|
0
|
|
|
|
|
$info->{documentation_url} = $base_url . $doc_url if $ds->{feature}{documentation}; |
406
|
0
|
|
|
|
|
|
$info->{data_url} = $base_url . $data_url; |
407
|
|
|
|
|
|
|
|
408
|
0
|
|
|
|
|
|
return $info; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
sub data_info_keys { |
413
|
|
|
|
|
|
|
|
414
|
0
|
|
|
0
|
1
|
|
return $_[0]->{ds}->data_info_keys; |
415
|
|
|
|
|
|
|
} |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
# contact_info ( ) |
419
|
|
|
|
|
|
|
# |
420
|
|
|
|
|
|
|
# Return a hash of information indicating who to contact about this data service. |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
sub contact_info { |
423
|
|
|
|
|
|
|
|
424
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
425
|
|
|
|
|
|
|
|
426
|
0
|
|
|
|
|
|
my $ds = $self->{ds}; |
427
|
0
|
|
|
|
|
|
return $ds->contact_info; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
# node_attr ( ) |
432
|
|
|
|
|
|
|
# |
433
|
|
|
|
|
|
|
# Return the specified attribute of the node that matches this request. |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
sub node_attr { |
436
|
|
|
|
|
|
|
|
437
|
0
|
|
|
0
|
1
|
|
my ($self, $attr) = @_; |
438
|
|
|
|
|
|
|
|
439
|
0
|
|
|
|
|
|
my $ds = $self->{ds}; |
440
|
0
|
|
|
|
|
|
my $path = $self->node_path; |
441
|
|
|
|
|
|
|
|
442
|
0
|
|
|
|
|
|
return $ds->node_attr($path, $attr); |
443
|
|
|
|
|
|
|
} |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
# special_value ( param ) |
446
|
|
|
|
|
|
|
# |
447
|
|
|
|
|
|
|
# Return the value of the specified special param, if it is enabled, and if |
448
|
|
|
|
|
|
|
# it was specified. Return undefined otherwise. |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
sub special_value { |
451
|
|
|
|
|
|
|
|
452
|
0
|
|
|
0
|
1
|
|
my ($self, $param) = @_; |
453
|
|
|
|
|
|
|
|
454
|
0
|
|
|
|
|
|
my $ds = $self->{ds}; |
455
|
|
|
|
|
|
|
|
456
|
0
|
|
0
|
|
|
|
my $param_name = $ds->special_param($param) || return; |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
# If we have already passed the params through HTTP::Validate, return the |
459
|
|
|
|
|
|
|
# cleaned value. |
460
|
|
|
|
|
|
|
|
461
|
0
|
0
|
|
|
|
|
if ( ref $self->{valid} ) |
462
|
|
|
|
|
|
|
{ |
463
|
0
|
|
|
|
|
|
my $value = $self->{valid}->value($param_name); |
464
|
0
|
0
|
|
|
|
|
return @$value if ref $value eq 'ARRAY'; |
465
|
0
|
0
|
|
|
|
|
return $value if defined $value; |
466
|
0
|
|
|
|
|
|
return; # otherwise |
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
# Otherwise, return the raw value if it exists and undefined otherwise. |
470
|
|
|
|
|
|
|
|
471
|
0
|
|
|
|
|
|
return $self->{raw_params}{$param_name}; |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
# special_given ( param ) |
476
|
|
|
|
|
|
|
# |
477
|
|
|
|
|
|
|
# Return true if the given special parameter was specified in the request, |
478
|
|
|
|
|
|
|
# regardless of its value. |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
sub special_given { |
481
|
|
|
|
|
|
|
|
482
|
0
|
|
|
0
|
1
|
|
my ($self, $param) = @_; |
483
|
|
|
|
|
|
|
|
484
|
0
|
|
|
|
|
|
my $ds = $self->{ds}; |
485
|
0
|
|
0
|
|
|
|
my $param_name = $ds->special_param($param) || return; |
486
|
|
|
|
|
|
|
|
487
|
0
|
|
|
|
|
|
return exists $self->{raw_params}{$param_name}; |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
# default_limit ( ) |
492
|
|
|
|
|
|
|
# |
493
|
|
|
|
|
|
|
# Return the default result limit, if any. Return undefined otherwise. |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
sub default_limit { |
496
|
|
|
|
|
|
|
|
497
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
498
|
|
|
|
|
|
|
|
499
|
0
|
|
|
|
|
|
my $path = $self->{node_path}; |
500
|
0
|
|
|
|
|
|
return $self->{ds}->node_attr($path, 'default_limit'); |
501
|
|
|
|
|
|
|
} |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
sub set_scratch { |
505
|
|
|
|
|
|
|
|
506
|
0
|
|
|
0
|
0
|
|
my ($self, $key, $value) = @_; |
507
|
|
|
|
|
|
|
|
508
|
0
|
|
|
|
|
|
return $self->{ds}->set_scratch($key, $value); |
509
|
|
|
|
|
|
|
} |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
sub get_scratch { |
513
|
|
|
|
|
|
|
|
514
|
0
|
|
|
0
|
0
|
|
my ($self, $key) = @_; |
515
|
|
|
|
|
|
|
|
516
|
0
|
|
|
|
|
|
return $self->{ds}->get_scratch($key); |
517
|
|
|
|
|
|
|
} |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
sub add_warning { |
521
|
|
|
|
|
|
|
|
522
|
0
|
|
|
0
|
1
|
|
my ($self, $warn_msg) = @_; |
523
|
|
|
|
|
|
|
|
524
|
0
|
0
|
|
|
|
|
$self->{warnings} = [] unless ref $self->{warnings} eq 'ARRAY'; |
525
|
0
|
|
|
|
|
|
push @{$self->{warnings}}, $warn_msg; |
|
0
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
sub warnings { |
530
|
|
|
|
|
|
|
|
531
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
532
|
|
|
|
|
|
|
|
533
|
0
|
0
|
|
|
|
|
return @{$self->{warnings}} if ref $self->{warnings} eq 'ARRAY'; |
|
0
|
|
|
|
|
|
|
534
|
0
|
|
|
|
|
|
return; |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
sub errors { |
539
|
|
|
|
|
|
|
|
540
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
541
|
|
|
|
|
|
|
|
542
|
0
|
0
|
|
|
|
|
return @{$self->{errors}} if ref $self->{errors} eq 'ARRAY'; |
|
0
|
|
|
|
|
|
|
543
|
0
|
|
|
|
|
|
return; |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
sub cautions { |
548
|
|
|
|
|
|
|
|
549
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
550
|
|
|
|
|
|
|
|
551
|
0
|
0
|
|
|
|
|
return {@$self->{cautions}} if ref $self->{cautions} eq 'ARRAY'; |
552
|
0
|
|
|
|
|
|
return; |
553
|
|
|
|
|
|
|
} |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
sub error_result { |
557
|
|
|
|
|
|
|
|
558
|
0
|
|
|
0
|
1
|
|
my ($self, $error) = @_; |
559
|
|
|
|
|
|
|
|
560
|
0
|
|
|
|
|
|
return $self->{ds}->error_result($error, $self); |
561
|
|
|
|
|
|
|
} |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
=head1 NAME |
564
|
|
|
|
|
|
|
|
565
|
|
|
|
|
|
|
Web::DataService::Request - object class for data service requests |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=head1 SYNOPSIS |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
As each incoming request is handled by the Web::DataService framework, a |
570
|
|
|
|
|
|
|
request object is created to represent it. This object is blessed into a |
571
|
|
|
|
|
|
|
subclass of Web::DataService::Request which provides the methods listed here |
572
|
|
|
|
|
|
|
and also includes one or more L with methods that you have |
573
|
|
|
|
|
|
|
written for evaluating the request and doing the appropriate fetching/storing |
574
|
|
|
|
|
|
|
on the backend data system. |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
The simplest way for the main application to handle a request is as follows: |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
Web::DataService->handle_request(request); |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
This call uses the C function provided by the foundation framework |
581
|
|
|
|
|
|
|
(L) to get the "outer" object representing this request from the point |
582
|
|
|
|
|
|
|
of view of the foundation framework, and then passes it to the |
583
|
|
|
|
|
|
|
L |
584
|
|
|
|
|
|
|
method of Web::DataService. In the process of handling the request, a new |
585
|
|
|
|
|
|
|
"inner" request object is generated and blessed into an appropriate subclass |
586
|
|
|
|
|
|
|
of Web::DataService::Request. |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
If you wish more control over this process, you can substitute the following: |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
my $inner = Web::DataService->new_request(request); |
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
# You can put code here to check the attributes of $inner and possibly |
593
|
|
|
|
|
|
|
# alter them... |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
$inner->execute; |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
Whichever of these code fragments you use should go into a Dancer L
|
598
|
|
|
|
|
|
|
handler|Dancer/"USAGE">. |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=head2 Request handling process |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
The request handling process carried out by |
603
|
|
|
|
|
|
|
L works |
604
|
|
|
|
|
|
|
as follows: |
605
|
|
|
|
|
|
|
|
606
|
|
|
|
|
|
|
=over |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
=item 1. |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
The request URL path and parameters are parsed according to the active set of |
611
|
|
|
|
|
|
|
data service features and special parameters. Depending upon the set of data |
612
|
|
|
|
|
|
|
service features that are active, the path may be processed before moving on |
613
|
|
|
|
|
|
|
to the next step. The following is not an exhaustive list, but illustrates |
614
|
|
|
|
|
|
|
the kinds of processing that are done: |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
=over |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
=item * |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
If more than one data service is defined, the appropriate one is selected to |
621
|
|
|
|
|
|
|
handle this request. |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
=item * |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
If the data service has the attribute "path_prefix", this prefix is removed |
626
|
|
|
|
|
|
|
from the path. |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
=item * |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
If the feature 'format_suffix' is active and the path ends in a format suffix |
631
|
|
|
|
|
|
|
such as C<.json>, then that suffix is removed and later used to set the |
632
|
|
|
|
|
|
|
"format" attribute of the request. |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
=item * |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
If the feature 'doc_paths' is active and the path ends in '_doc' or in |
637
|
|
|
|
|
|
|
'/index' then this suffix is removed and the "is_doc_request" attribute of the |
638
|
|
|
|
|
|
|
request is set. |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
=item * |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
If the special parameter 'document' is active and this parameter was included |
643
|
|
|
|
|
|
|
with the request, then the "is_doc_request" attribute of the request is set. |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
=back |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
=item 2. |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
The modified request path is matched against the set of data service node |
650
|
|
|
|
|
|
|
paths. Nodes with either of the attributes C or C |
651
|
|
|
|
|
|
|
match as prefixes, all others must match exactly. If none of the nodes match, |
652
|
|
|
|
|
|
|
then the request is rejected with a HTTP 404 error. Otherwise, a new request |
653
|
|
|
|
|
|
|
object is created and configured using the attributes of the matching node. |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
=back |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
If you used L |
658
|
|
|
|
|
|
|
instead of L
|
659
|
|
|
|
|
|
|
] )">, then you get control at this point and can modify the request before |
660
|
|
|
|
|
|
|
calling C<< $request->execute >> to finish the process. |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
=over |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
=item 3. |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
If the matching node has the C attribute, then the contents of the |
667
|
|
|
|
|
|
|
specified file are returned using the foundation framework (i.e. Dancer). If |
668
|
|
|
|
|
|
|
the node has the C attribute instead, then the remainder of the |
669
|
|
|
|
|
|
|
request path is applied as a relative path to that directory. The result of |
670
|
|
|
|
|
|
|
the request will be either the contents of a matching file or a HTTP 404 |
671
|
|
|
|
|
|
|
error. |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=item 4. |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
Otherwise, the new request will be blessed into an automatically generated |
676
|
|
|
|
|
|
|
subclass of Web::DataService::Request. These subclasses are generated |
677
|
|
|
|
|
|
|
according to the value of the "role" attribute of the matching node. Each |
678
|
|
|
|
|
|
|
different role generates two subclasses, one for documentation requests and |
679
|
|
|
|
|
|
|
one for operation requests. These classes are composed so that they contain |
680
|
|
|
|
|
|
|
the necessary methods for documentation rendering and operation execution, |
681
|
|
|
|
|
|
|
respectively, along with all of the definitions from the primary role (this |
682
|
|
|
|
|
|
|
role module must be written by the application author). |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
=item 5. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
If the "is_doc_request" attribute has been set, or if the matching node does |
687
|
|
|
|
|
|
|
not have a value for the "method" attribute, then the documentation directory |
688
|
|
|
|
|
|
|
is checked for a template corresponding to the matching node. If not found, |
689
|
|
|
|
|
|
|
the appropriate default template is used. This template is rendered to |
690
|
|
|
|
|
|
|
produce a documentation page, which is returned as the result of the request. |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
=item 6. |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
Otherwise, we can assume that the node has a "method" attribute. The request |
695
|
|
|
|
|
|
|
parameters are then checked against the ruleset named by the "ruleset" |
696
|
|
|
|
|
|
|
attribute, or the ruleset corresponding to the node path if this attribute is |
697
|
|
|
|
|
|
|
not set. |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
=item 7. |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
The output is then configured according to the output blocks(s) indicated by the |
702
|
|
|
|
|
|
|
"output" attribute plus those indicated by "optional_output" in conjunction |
703
|
|
|
|
|
|
|
with the special parameter "show". |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
=item 8. |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
The method specified by the node attribute "method" is then called. This |
708
|
|
|
|
|
|
|
method (which must be written by the application author) is responsible for |
709
|
|
|
|
|
|
|
fetching and/or storing data using the backend system and specifying what the |
710
|
|
|
|
|
|
|
result of the operation should be. |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
=item 9. |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
If the result of the operation is one or more data records, these records are |
715
|
|
|
|
|
|
|
processed according to the specification contained in the selected output |
716
|
|
|
|
|
|
|
block(s), and are then serialized by the module corresponding to the selected |
717
|
|
|
|
|
|
|
output format. If "count" or "datainfo" were requested, or if any warnings or |
718
|
|
|
|
|
|
|
errors were generated during the execution of the request, this material is |
719
|
|
|
|
|
|
|
included in an appropriate way by the serialization module. The resulting |
720
|
|
|
|
|
|
|
response body is returned using the foundation framework. |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
=item 10. |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
If the result of the operation is instead a piece of non-record data (i.e. an |
725
|
|
|
|
|
|
|
image or other binary data), it is returned as the response body using the |
726
|
|
|
|
|
|
|
foundation framework. |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
=back |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
=head1 METHODS |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
=head2 Constructor |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=head3 new ( attributes... ) |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
You will not need to call this method directly; instead, you should call the |
737
|
|
|
|
|
|
|
L |
738
|
|
|
|
|
|
|
method of Web::DataService, which calls it internally after carrying out other |
739
|
|
|
|
|
|
|
processing. |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
=head2 Execution |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
=head3 execute ( ) |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
Executes this request, and returns the serialized response data. If your main |
746
|
|
|
|
|
|
|
application uses C, then you will not need to call this |
747
|
|
|
|
|
|
|
method because C calls it internally. |
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
=head3 error_result ( error ) |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
Aborts processing of the request and causes a HTTP error response to be |
752
|
|
|
|
|
|
|
returned to the client. You will probably not need to call this method, since |
753
|
|
|
|
|
|
|
the preferred way of generating an error condition is to call |
754
|
|
|
|
|
|
|
L. The parameter can be any of the following: |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
=over |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
=item * |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
A HTTP error code, such as "404" or "500". |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
=item * |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
An error message, which will be written to the log. For security reasons, the |
765
|
|
|
|
|
|
|
client will just get back a HTTP 500 response that tells them a server error |
766
|
|
|
|
|
|
|
occurred and they should contact the server administrator. |
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
=item * |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
A validation result object from L. The client will get back a |
771
|
|
|
|
|
|
|
HTTP 400 response containing the error and warning messages contained within |
772
|
|
|
|
|
|
|
it. |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
=back |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
=head2 Attribute accessors |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
=head3 ds |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
Returns a reference to the data service instance with which this request is |
781
|
|
|
|
|
|
|
associated. |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
=head3 outer |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
Returns a reference to the "outer" request object defined by the foundation |
786
|
|
|
|
|
|
|
framework. |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=head3 path |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
Returns the raw path associated with the request. |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
=head3 node_path |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
Returns the path of the node that matches this request. |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
=head3 rest_path |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
If the node path matches the processed request path as a prefix, this accessor returns |
799
|
|
|
|
|
|
|
the remainder of the path. Otherwise, it returns C. |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
=head3 is_invalid_request |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
Returns true if this request could not be matched to a node, or is otherwise |
804
|
|
|
|
|
|
|
invalid. Returns false otherwise. |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
=head3 is_doc_request |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
Returns true if this request has been determined to be a request for |
809
|
|
|
|
|
|
|
documentation, according to the features and special parameters enabled for |
810
|
|
|
|
|
|
|
this data service. Returns false otherwise. |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
=head3 is_node_path |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
Returns true if the request path I matches the path of a data service |
815
|
|
|
|
|
|
|
node, false otherwise. |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
=head3 http_method |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
Returns (or sets) the HTTP method associated with the request. |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
=head3 request_url |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
Returns the complete request URL. |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
=head3 base_url |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
Returns the base component of the request URL, of the form |
828
|
|
|
|
|
|
|
"http://some.host/" or something similar. |
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
=head3 root_url |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
Returns the base URL plus the path prefix (if any) for this data service. |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
=head3 path_prefix |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
Returns the path prefix (if any) for this data service. |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=head3 data_info |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
Returns a hash containing information about the request and the data to be |
841
|
|
|
|
|
|
|
returned. The hash keys will include some or all of the following, depending |
842
|
|
|
|
|
|
|
upon the configuration of the data service. |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
=over |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
=item title, data_provider, data_source, data_license, license_url |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
The values of these keys will be the corresponding attributes of the data |
849
|
|
|
|
|
|
|
service. They may be undefined if no value was specified for them either when |
850
|
|
|
|
|
|
|
the data service was instantiated or in the configuration file maintained by |
851
|
|
|
|
|
|
|
the foundation framework. |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
=item access_time |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
The current time. |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
=item data_url |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
The complete request URL. |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
=item documentation_url |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
A URL that will return a documentation page describing the selected data |
864
|
|
|
|
|
|
|
service node. |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
=back |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
=head3 data_info_keys |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
Returns a list of the keys documented for C, in a canonical order |
871
|
|
|
|
|
|
|
for use by the serialization modules. |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
=head3 contact_info |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
Returns a hash whose keys are C and C. The values will be the |
876
|
|
|
|
|
|
|
values of the data service attributes C and C, |
877
|
|
|
|
|
|
|
respectively. |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
=head3 generate_url ( attrs ) |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
This method returns a URL generated from the specified attributes, which must be given |
882
|
|
|
|
|
|
|
either as a hashref or as a string: |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
# either of the following: |
885
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
$url = $request->generate_url( { op => 'abc/def', format => 'json', params => 'foo=1' } ); |
887
|
|
|
|
|
|
|
$url = $request->generate_url( "op:abc/def.json?foo=1" ); |
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
The attributes are as follows: |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=over |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
=item node |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
Generate a URL which will request documentation using the node path given by |
896
|
|
|
|
|
|
|
the value of this attribute. In the string form, this is represented by a |
897
|
|
|
|
|
|
|
prefix of "node:". |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
=item op |
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
Generate a URL which will request a data service operation using the node path |
902
|
|
|
|
|
|
|
given by the value of this attribute. In the string form, this is represented |
903
|
|
|
|
|
|
|
by a prefix of "op:". |
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
=item path |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
Generate a URL which will request the exact path given. This is used to |
908
|
|
|
|
|
|
|
generate URLs for requesting files, such as CSS files. In the string form, |
909
|
|
|
|
|
|
|
this is represented by a prefix of "path:". |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
=item format |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
The generated URL will request output in the specified format. Depending upon |
914
|
|
|
|
|
|
|
the features enabled for this data service, that may mean either adding the |
915
|
|
|
|
|
|
|
specified value as a suffix to the URL path, or adding a special parameter. |
916
|
|
|
|
|
|
|
In the string form, this is represented by adding '.' followed by the format |
917
|
|
|
|
|
|
|
to the path (this syntax is fixed no matter which data service features are |
918
|
|
|
|
|
|
|
enabled). |
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
=item params |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
Configure the URL to include the specified parameters. The value of this |
923
|
|
|
|
|
|
|
attribute must be either an arrayref with an even number of elements or a |
924
|
|
|
|
|
|
|
single URL parameter string such as C<"foo=1&bar=2">. In the string form, |
925
|
|
|
|
|
|
|
this is represented by a '?' followed by the parameter string. |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
=item type |
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
The value of this attribute must be either C, C, or C. If |
930
|
|
|
|
|
|
|
"abs" is given, then the generated URL will begin with |
931
|
|
|
|
|
|
|
"http[s]://hostname[:port]/. If "site", then the generated URL will begin |
932
|
|
|
|
|
|
|
with "/" followed by the path prefix for this data service (if any). If |
933
|
|
|
|
|
|
|
"relative", no prefix will be added to the generated URL. In this case, you |
934
|
|
|
|
|
|
|
must make sure to specify a path that will work properly relative to the URL |
935
|
|
|
|
|
|
|
of the page on which you intend to display it. |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
If this attribute is not specified, it defaults to "site". In the string |
938
|
|
|
|
|
|
|
form, this is represented by modifying the prefix, i.e. "oprel:" or "opabs:" |
939
|
|
|
|
|
|
|
instead of just "op:". |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
=back |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
=head3 node_attr ( name ) |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
Returns the value of the specified attribute of the node matching this |
946
|
|
|
|
|
|
|
request, or I if the attribute is not defined for that node. |
947
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
=head3 special_value ( param ) |
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
Returns the value of the specified special parameter, if it is enabled for |
951
|
|
|
|
|
|
|
this data service and if it was included with this request. Returns I |
952
|
|
|
|
|
|
|
otherwise. |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
=head3 special_given ( param ) |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
Returns true if the specified special parameter was included in this request |
957
|
|
|
|
|
|
|
and is enabled for this data service, regardless of its value. Returns false |
958
|
|
|
|
|
|
|
otherwise. |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
=head3 default_limit |
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
Returns the default result limit, if any. This is used in generating |
963
|
|
|
|
|
|
|
documentation. |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
=head2 Documentation methods |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
The following methods are only available with documentation requests. They can |
968
|
|
|
|
|
|
|
be called from documentation templates as follows: |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
<% result = request.method_name(args) %> |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
or, to include the result directly in the rendered output: |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
<% request.method_name(args) %> |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
In either case, "request" is a variable automatically provided to the |
977
|
|
|
|
|
|
|
templating engine. The string "result" should be replaced by whatever |
978
|
|
|
|
|
|
|
variable you wish to assign the result to, and "method_name" and "args" by the |
979
|
|
|
|
|
|
|
desired method and arguments. |
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
These methods are all packaged up in blocks defined by doc_defs.tt, so you |
982
|
|
|
|
|
|
|
will not need to call them directly unless you want to make substantive |
983
|
|
|
|
|
|
|
changes to the look of the documentation pages. |
984
|
|
|
|
|
|
|
|
985
|
|
|
|
|
|
|
=head3 document_node |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
Returns the documentation string for the node matching this request, or the |
988
|
|
|
|
|
|
|
empty string if none was defined. |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
=head3 list_navtrail |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
Returns a list of navigation trail components for the current request, in Pod |
993
|
|
|
|
|
|
|
format. These are generated componentwise from the node path. |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
=head3 document_usage |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
Returns a string in Pod format listing the URLs generated from the node |
998
|
|
|
|
|
|
|
attribute "usage", if any were given for this node. |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
=head3 list_subnodes |
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
Returns a list of the node paths corresponding to all subnodes of the current |
1003
|
|
|
|
|
|
|
one for which the C attribute was set. |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
=head3 document_subnodes |
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
Returns a string in Pod format documenting the subnodes of the current one for |
1008
|
|
|
|
|
|
|
which the C attribute was set. |
1009
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
=head3 document_params |
1011
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
Returns a string in Pod format documenting the parameters available for this |
1013
|
|
|
|
|
|
|
request. This is automatically generated from the corresponding ruleset, if |
1014
|
|
|
|
|
|
|
one was defined. |
1015
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
=head3 list_http_methods |
1017
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
Returns a list of HTTP methods that are allowed for this request path. |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
=head3 document_http_methods |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
Returns a string in Pod format documenting the HTTP methods that are allowed |
1023
|
|
|
|
|
|
|
for this request path. |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
=head3 document_response |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
Returns a string in Pod format documenting the all of the fields that might be |
1028
|
|
|
|
|
|
|
included in the result. |
1029
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
=head3 output_label |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
Returns the value of the node attribute "output_label", or the default value |
1033
|
|
|
|
|
|
|
"basic" if none was defined. |
1034
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
=head3 optional_output |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
Returns the value of the node attribute "optional_output", if this attribute |
1038
|
|
|
|
|
|
|
was defined. |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
=head3 document_formats ( options ) |
1041
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
Returns a string in Pod format documenting the formats allowed for this |
1043
|
|
|
|
|
|
|
node. If a parameter is specified, it must be a hashref. If this includes |
1044
|
|
|
|
|
|
|
the key 'all' with a true value, then all formats defined for this |
1045
|
|
|
|
|
|
|
data service are included. If it includes the key 'extended' with a true value, then |
1046
|
|
|
|
|
|
|
a description of each format is included. |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
=head3 default_format |
1049
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
Return the name of the default format (if any was specified) for this node. |
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
=head3 document_vocabs ( options ) |
1053
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
Return a string in Pod format documenting the vocabularies allowed for this |
1055
|
|
|
|
|
|
|
node. If a parameter is specified, it must be a hashref. If this includes |
1056
|
|
|
|
|
|
|
the key 'all' with a true value, then all vocabularies defined for this |
1057
|
|
|
|
|
|
|
data service are included. If it includes the key 'extended' with a true value, then |
1058
|
|
|
|
|
|
|
a description of each vocabulary is included. |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
=head3 output_format |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
You can use this method to check whether the response is to be rendered into |
1063
|
|
|
|
|
|
|
HTML or returned as Pod text. The values returned are C and |
1064
|
|
|
|
|
|
|
respectively. |
1065
|
|
|
|
|
|
|
|
1066
|
|
|
|
|
|
|
=head2 Operation methods |
1067
|
|
|
|
|
|
|
|
1068
|
|
|
|
|
|
|
The following methods are only available with operation requests. They can be |
1069
|
|
|
|
|
|
|
called from any of the operation methods included in the application role |
1070
|
|
|
|
|
|
|
module(s). |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
=head3 get_connection |
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
This method can only be used if you explicitly specified a backend plugin when |
1075
|
|
|
|
|
|
|
instantiating the data service, or if the module L |
1076
|
|
|
|
|
|
|
was required in your main application before Web::DataService. |
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
Assuming that the proper connection information is present in the application |
1079
|
|
|
|
|
|
|
configuration file, this method will return a connection to your backend data |
1080
|
|
|
|
|
|
|
store. |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
=head3 exception ( code, message ) |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
Returns an exception object encoding the specified HTTP result code and a message to go with |
1085
|
|
|
|
|
|
|
it. This exception object can be used as an argument to 'die'. Its type is |
1086
|
|
|
|
|
|
|
C. |
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
=head3 debug |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
Returns true if the data service process is running under debug mode. This can be used to output |
1091
|
|
|
|
|
|
|
extra debugging information as appropriate. |
1092
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
=head3 debug_line ( text ) |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
Print the specified text to standard error, followed by a newline, if debug mode is enabled for |
1096
|
|
|
|
|
|
|
this data service process. This can be used, for example, to output the text of SQL statements |
1097
|
|
|
|
|
|
|
executed on the underlying database, and similar information, for debugging purposes. For example: |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
$request->debug_line($sql) if $request->debug; |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
=head3 param_keys ( ) |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
Returns a list of the parameter keys corresponding to the request parameters. |
1104
|
|
|
|
|
|
|
These will generally be the same as the parameter names, but may |
1105
|
|
|
|
|
|
|
be different if you include the keys C and/or C in the parameter |
1106
|
|
|
|
|
|
|
validation rulesets (see L). |
1107
|
|
|
|
|
|
|
|
1108
|
|
|
|
|
|
|
=head3 clean_param ( param ) |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
Returns the cleaned value of the specified parameter, or undefined if the |
1111
|
|
|
|
|
|
|
parameter was not included in the request. If more than one parameter value was |
1112
|
|
|
|
|
|
|
given, the result will be an array ref. |
1113
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
=head3 clean_param_list ( param ) |
1115
|
|
|
|
|
|
|
|
1116
|
|
|
|
|
|
|
Returns a list of all the cleaned values of the specified parameter (one or |
1117
|
|
|
|
|
|
|
more), or empty if the parameter was not included in the request. |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
=head3 clean_param_hash ( param ) |
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
Returns a hashref whose keys are all of the cleaned values of the specified |
1122
|
|
|
|
|
|
|
parameter, or an empty hashref if the parameter was not included in the |
1123
|
|
|
|
|
|
|
request. |
1124
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
=head3 param_given ( param ) |
1126
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
Returns true if the specified parameter was included in there request, whether |
1128
|
|
|
|
|
|
|
or not it had a valid value. Returns false otherwise. |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
=head3 params_for_display |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
Returns a list of (parameter, value) pairs for use in responding to the |
1133
|
|
|
|
|
|
|
'datainfo' special parameter. This result list leaves out any special |
1134
|
|
|
|
|
|
|
parameters that do not affect the content of the result. Multiple values are |
1135
|
|
|
|
|
|
|
concatenated together using commas. |
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
=head3 validate_params ( ruleset_name, param... ) |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
Validates the specified parameters (which may be hash or list refs of parameters and values) to |
1140
|
|
|
|
|
|
|
the specified ruleset. Returns the result, which will be an object of type HTTP::Validate::Result |
1141
|
|
|
|
|
|
|
that can then be queried for success or failure, error messages, etc. The primary purpose for this |
1142
|
|
|
|
|
|
|
method is to allow validation of data records before they are added to the underlying database. |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
=head3 raw_body |
1145
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
Returns the request body as an un-decoded string. If the request does not contain a body, returns |
1147
|
|
|
|
|
|
|
the empty string. The primary purpose for this method is to accept data for addition to the |
1148
|
|
|
|
|
|
|
underlying database. |
1149
|
|
|
|
|
|
|
|
1150
|
|
|
|
|
|
|
=head3 decode_body |
1151
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
Attempts to decode the request body, if it is in a known format. Currently, the only two formats |
1153
|
|
|
|
|
|
|
understood are JSON and text. A JSON body will be decoded into a Perl data structure, while a text |
1154
|
|
|
|
|
|
|
body will be split into a list of lines. If no body exists, the undefined value is returned. If an |
1155
|
|
|
|
|
|
|
error occurs during JSON decoding, it will be returned as a second item. Consequently, the return |
1156
|
|
|
|
|
|
|
value of this method should be assigned to a two-element list. |
1157
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
=head3 has_block ( block ) |
1159
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
Returns true if the specified output block was selected for this request. The |
1161
|
|
|
|
|
|
|
parameter can be either the name of the block or the parameter value by which |
1162
|
|
|
|
|
|
|
it would be selected. |
1163
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
=head3 select_list ( subst ) |
1165
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
Returns a list of strings derived from the 'select' configuration records |
1167
|
|
|
|
|
|
|
found in the output blocks selected for this request. You can use these |
1168
|
|
|
|
|
|
|
records to specify which fields need to be retrieved from the backend data |
1169
|
|
|
|
|
|
|
store. Any given string will only appear once in the list, even if it occurs |
1170
|
|
|
|
|
|
|
in multiple 'select' records. |
1171
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
The optional argument should be a hashref, indicating substitutions to be |
1173
|
|
|
|
|
|
|
made. For example, given the following code, |
1174
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
$ds->define_block( 'block1' => |
1176
|
|
|
|
|
|
|
{ select => '$a.name', '$a.value', 'c.size' }, |
1177
|
|
|
|
|
|
|
... ); |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
# ...and in a different subroutine... |
1180
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
my @fields = $request->select_list( { a => 'table1', b => 'table2' } ) |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
The result will include C, C, and C. |
1184
|
|
|
|
|
|
|
|
1185
|
|
|
|
|
|
|
If you are using an SQL-based backend, and if you set up the 'select' records |
1186
|
|
|
|
|
|
|
properly, you can use this method (or see C below) to build a |
1187
|
|
|
|
|
|
|
SELECT statement that will fetch exactly the information needed for the |
1188
|
|
|
|
|
|
|
selected set of output blocks. This is important if your application allows |
1189
|
|
|
|
|
|
|
optional output blocks that can be selected arbitrarily by the client. If you |
1190
|
|
|
|
|
|
|
are using a non-SQL backend, you are free to use this in any way that makes |
1191
|
|
|
|
|
|
|
sense given the backend interface. |
1192
|
|
|
|
|
|
|
|
1193
|
|
|
|
|
|
|
=head3 select_hash ( subst ) |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
Returns the same set of strings as C, but as the keys in a |
1196
|
|
|
|
|
|
|
hash. The values will all be 1. |
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
=head3 select_string ( subst ) |
1199
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
Returns the same set of strings as C, but joined into a single |
1201
|
|
|
|
|
|
|
string with each item separated by a comma and a space. |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
=head3 substitute_select ( variable => value, variable => value ... ) |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
Make substitutions in the select list. For example, if passed the arguments 'v => xt', then |
1206
|
|
|
|
|
|
|
anywhere the string '$v' appears in the select list, that string will be replaced by 'xt'. This |
1207
|
|
|
|
|
|
|
method should be called before 'select_list' or 'select_string'. The intended use is to select |
1208
|
|
|
|
|
|
|
between one or more alternate database tables. |
1209
|
|
|
|
|
|
|
|
1210
|
|
|
|
|
|
|
=head3 tables_hash |
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
Returns a hashref whose keys are derived from the 'select' configuration |
1213
|
|
|
|
|
|
|
records found in the output blocks selected for this request. The keys from |
1214
|
|
|
|
|
|
|
this hash will be the values specified by any 'tables' attributes in those |
1215
|
|
|
|
|
|
|
configuration records. The values will all be 1. |
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
If you are using an SQL-based backend, and if you set up the 'select' records |
1218
|
|
|
|
|
|
|
properly, you can use this method to keep track of which database tables will |
1219
|
|
|
|
|
|
|
be needed in order to build a query that can satisfy all of the data blocks |
1220
|
|
|
|
|
|
|
included in this request. You can use the set of keys to constuct an |
1221
|
|
|
|
|
|
|
appropriate list of table joins. If you are using a non-SQL backend, you can |
1222
|
|
|
|
|
|
|
use this in any way that makes sense given the backend interface. |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
If you call this method multiple times, you will get a reference to the same |
1225
|
|
|
|
|
|
|
hash each time. This means that you can safely add and remove keys during |
1226
|
|
|
|
|
|
|
your own processing. |
1227
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
=head3 add_table ( alias, [full_name] ) |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
Add an extra key to the tables hash. The optional second parameter can be the full name of the |
1231
|
|
|
|
|
|
|
table to be included, but this is ignored. Note that adding a table to the table hash will I |
1232
|
|
|
|
|
|
|
automatically include that table in any SQL statements. You need to check the table hash and add |
1233
|
|
|
|
|
|
|
it yourself if the appropriate key is found. |
1234
|
|
|
|
|
|
|
|
1235
|
|
|
|
|
|
|
=head3 filter_hash |
1236
|
|
|
|
|
|
|
|
1237
|
|
|
|
|
|
|
Returns a hashref whose keys are derived from the 'filter' configuration |
1238
|
|
|
|
|
|
|
records found in the output blocks selected for this request. The values will |
1239
|
|
|
|
|
|
|
all be 1. |
1240
|
|
|
|
|
|
|
|
1241
|
|
|
|
|
|
|
If you are using an SQL-based backend, and if you set up the 'filter' records |
1242
|
|
|
|
|
|
|
properly, you can use this method to get a list of (unique) filter expressions |
1243
|
|
|
|
|
|
|
to use in building a query that can satisfy all of the data blocks included in |
1244
|
|
|
|
|
|
|
this request. (Note: you will almost always need to add other filter |
1245
|
|
|
|
|
|
|
expressions derived from parameter values as well). If you are using a |
1246
|
|
|
|
|
|
|
non-SQL backend, you can use this in any way that makes sense given the |
1247
|
|
|
|
|
|
|
backend interface. |
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
If you call this method multiple times, you will get a reference to the same |
1250
|
|
|
|
|
|
|
hash each time. This means that you can safely add and remove keys during |
1251
|
|
|
|
|
|
|
your own processing. |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
=head3 output_field_list |
1254
|
|
|
|
|
|
|
|
1255
|
|
|
|
|
|
|
This method returns the output field list for the current request. This is the actual list, not a |
1256
|
|
|
|
|
|
|
copy, so it can be manipulated. This is a real hack, which will probably be removed from a future |
1257
|
|
|
|
|
|
|
version of this module. But for the time being, you can use it (for example) to go through the |
1258
|
|
|
|
|
|
|
list and prune fields that will not be used. |
1259
|
|
|
|
|
|
|
|
1260
|
|
|
|
|
|
|
=head3 delete_output_field ( field ) |
1261
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
Remove the specified output field from the list. The first field whose name (not label) matches |
1263
|
|
|
|
|
|
|
the argument is removed, regardless of what output block it occurs in. If no fields match, nothing |
1264
|
|
|
|
|
|
|
will be removed. |
1265
|
|
|
|
|
|
|
|
1266
|
|
|
|
|
|
|
=head3 result_limit |
1267
|
|
|
|
|
|
|
|
1268
|
|
|
|
|
|
|
Returns the result limit specified for this request, or undefined if none was |
1269
|
|
|
|
|
|
|
given or if C was specified. Even though Web::DataService will always |
1270
|
|
|
|
|
|
|
truncate the result set if a limit was given, you may want to include this |
1271
|
|
|
|
|
|
|
limit value in any queries you make to the backend so as to prevent your |
1272
|
|
|
|
|
|
|
server from doing unnecessary work. |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
=head3 result_offset ( will_handle ) |
1275
|
|
|
|
|
|
|
|
1276
|
|
|
|
|
|
|
Returns true if a result offset was specified for this request, or zero if |
1277
|
|
|
|
|
|
|
none was specified. If the argument value is true, then Web::DataService |
1278
|
|
|
|
|
|
|
assumes that you will handle the process of offsetting the data result, |
1279
|
|
|
|
|
|
|
e.g. by using modifying your backend query appropriately (see |
1280
|
|
|
|
|
|
|
C below). |
1281
|
|
|
|
|
|
|
|
1282
|
|
|
|
|
|
|
If the argument is false, or if you never call either this method or |
1283
|
|
|
|
|
|
|
C, then (if an offset was specified for this request) |
1284
|
|
|
|
|
|
|
Web::DataService will automatically discard the corresponding number of |
1285
|
|
|
|
|
|
|
records from the beginning of the result set before serializing the results. |
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
=head3 sql_limit_clause ( will_handle ) |
1288
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
Returns a string whose value is an LIMIT clause that can be added to an SQL |
1290
|
|
|
|
|
|
|
query to generate a result set in accordance with result limit and offset (if |
1291
|
|
|
|
|
|
|
any) specified for this request. If the argument is true, then |
1292
|
|
|
|
|
|
|
Web::DataService assumes that you will actually do this. |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
If the argument is false, or if you never call either this method or |
1295
|
|
|
|
|
|
|
C, then (if an offset was specified for this request) |
1296
|
|
|
|
|
|
|
Web::DataService will automatically discard the corresponding number of |
1297
|
|
|
|
|
|
|
records from the beginning of the result set before serializing the results. |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
If a result limit was specified for this request, and if the result set you |
1300
|
|
|
|
|
|
|
generate exceeds this size, Web::DataService will always truncate it to match |
1301
|
|
|
|
|
|
|
the specified limit. |
1302
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
=head3 sql_count_clause ( ) |
1304
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
Returns a string that can be added to an SQL statement to generate a result |
1306
|
|
|
|
|
|
|
count in accordance with the request parameters. If the special parameter |
1307
|
|
|
|
|
|
|
"count" was specified for this request, the result will be |
1308
|
|
|
|
|
|
|
C. Otherwise, it will be the empty string. |
1309
|
|
|
|
|
|
|
|
1310
|
|
|
|
|
|
|
If you are using a non-SQL backend, you can still use this as a boolean |
1311
|
|
|
|
|
|
|
variable to determine if the result should include a count of the number of |
1312
|
|
|
|
|
|
|
records found. |
1313
|
|
|
|
|
|
|
|
1314
|
|
|
|
|
|
|
=head3 sql_count_rows ( ) |
1315
|
|
|
|
|
|
|
|
1316
|
|
|
|
|
|
|
Execute the SQL statement "SELECT FOUND ROWS" and store the result for use in generating the |
1317
|
|
|
|
|
|
|
response header. But only do this if the request parameters specify that result counts should |
1318
|
|
|
|
|
|
|
be returned. |
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
=head3 set_result_count ( count ) |
1321
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
Use this method to tell Web::DataService the result count if you are using |
1323
|
|
|
|
|
|
|
C. In this case, you will generally need to execute a separate query |
1324
|
|
|
|
|
|
|
such as "SELECT FOUND_ROWS()" after your main query. |
1325
|
|
|
|
|
|
|
|
1326
|
|
|
|
|
|
|
=head3 output_format |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
Returns the name of the response format selected for this request. |
1329
|
|
|
|
|
|
|
|
1330
|
|
|
|
|
|
|
=head3 output_vocab |
1331
|
|
|
|
|
|
|
|
1332
|
|
|
|
|
|
|
Returns the name of the response vocabulary selected for this request. If no |
1333
|
|
|
|
|
|
|
vocabularies have been defined for this data service, it will return "null", |
1334
|
|
|
|
|
|
|
the name of the default vocabulary. |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
=head3 output_linebreak |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
Returns the string to be inserted between output lines in text-based response |
1339
|
|
|
|
|
|
|
formats. This will be either a carriage return, a linefeed, or both. |
1340
|
|
|
|
|
|
|
|
1341
|
|
|
|
|
|
|
=head3 result_limit |
1342
|
|
|
|
|
|
|
|
1343
|
|
|
|
|
|
|
Returns the limit (if any) specified for the size of the result set. |
1344
|
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
=head3 result_offset |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
Returns the offset (if any) specified for the start of the result set. |
1348
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
=head3 display_header |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
Returns true if header material is to be displayed in text-based response |
1352
|
|
|
|
|
|
|
formats, false otherwise. |
1353
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
=head3 display_datainfo |
1355
|
|
|
|
|
|
|
|
1356
|
|
|
|
|
|
|
Returns true if a description of the dataset is to be included in |
1357
|
|
|
|
|
|
|
the response, false otherwise. |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
=head3 display_counts |
1360
|
|
|
|
|
|
|
|
1361
|
|
|
|
|
|
|
Returns true if result counts and elapsed time are to be included in the |
1362
|
|
|
|
|
|
|
response, false otherwise. |
1363
|
|
|
|
|
|
|
|
1364
|
|
|
|
|
|
|
=head3 save_output |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
Returns true if the special parameter 'save' was included in the request. |
1367
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
=head3 get_config |
1369
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
Returns a hashref providing access to the attributes defined in the |
1371
|
|
|
|
|
|
|
application configuration file. Allows you to include application-specific |
1372
|
|
|
|
|
|
|
directives in the file and retrieve them as needed from your operation |
1373
|
|
|
|
|
|
|
methods. |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
=head3 set_content_type |
1376
|
|
|
|
|
|
|
|
1377
|
|
|
|
|
|
|
Specify the value for the "Content-type" HTTP response header. You will |
1378
|
|
|
|
|
|
|
probably not need to call this, since it is set automatically based on the |
1379
|
|
|
|
|
|
|
selected response format. |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
=h3ad3 exception ( code, message ) |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
Returns an exception object which can be used as an argument to C. This |
1384
|
|
|
|
|
|
|
will abort processing of the current request and generate an HTTP error |
1385
|
|
|
|
|
|
|
result. The first argument must be a valid HTTP error code. |
1386
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
=head2 Result methods |
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
These methods are also available with operation requests. I
|
1390
|
|
|
|
|
|
|
call at least one of them from each of your operation methods.> These methods |
1391
|
|
|
|
|
|
|
are how you tell Web::DataService the result of each operation. |
1392
|
|
|
|
|
|
|
|
1393
|
|
|
|
|
|
|
You can make more than one of these calls from a single operation, but note |
1394
|
|
|
|
|
|
|
that each call (except for C in some cases) wipes out any result |
1395
|
|
|
|
|
|
|
specified by previous calls. |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
=head3 single_result ( record ) |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
The argument must be a hashref representing a single data record. The result |
1400
|
|
|
|
|
|
|
of this operation will be that single record. |
1401
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
=head3 list_result ( record... ) |
1403
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
You can call this method either with a single arrayref argument whose members |
1405
|
|
|
|
|
|
|
are hashrefs, or with a list of hashrefs. Either way, the result of this |
1406
|
|
|
|
|
|
|
operation will be the specified list of records. |
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
=head3 add_result ( record... ) |
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
Adds the specified record(s) to a result set previously specified by |
1411
|
|
|
|
|
|
|
C. All arguments must be hashrefs. |
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
=head3 sth_result ( sth ) |
1414
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
The argument must be a valid DBI statement handle that has already been |
1416
|
|
|
|
|
|
|
executed. Once your operation method returns, Web::DataService will then |
1417
|
|
|
|
|
|
|
fetch the result records from this sth one by one, process them according to |
1418
|
|
|
|
|
|
|
the selected set of output blocks for this request, and serialize the result. |
1419
|
|
|
|
|
|
|
|
1420
|
|
|
|
|
|
|
If you use this result method, you will need to call either C |
1421
|
|
|
|
|
|
|
or C to determine if a result count is needed. If so, |
1422
|
|
|
|
|
|
|
execute a "SELECT FOUND_ROWS()" query (or the equivalent) and use |
1423
|
|
|
|
|
|
|
C to tell Web::DataService how many records were found. |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
=head3 data_result ( data ) |
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
The argument must be either a scalar or a reference to a scalar. In either |
1428
|
|
|
|
|
|
|
case, this data will be returned as the result of the operation without any |
1429
|
|
|
|
|
|
|
further processing. You can use this, for example, to return images or other |
1430
|
|
|
|
|
|
|
binary data. You can use C to set the result content type, |
1431
|
|
|
|
|
|
|
or you can rely on the suffix of the URL path if appropriate. |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
=head3 clear_result |
1434
|
|
|
|
|
|
|
|
1435
|
|
|
|
|
|
|
This call clears any results that have been specified for this operation by |
1436
|
|
|
|
|
|
|
any of the other methods in this section. |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
=head3 add_warning ( message ) |
1439
|
|
|
|
|
|
|
|
1440
|
|
|
|
|
|
|
Add the specified warning message to this request. The warnings will be |
1441
|
|
|
|
|
|
|
automatically included in the result, in a manner appropriate for the selected |
1442
|
|
|
|
|
|
|
response format. |
1443
|
|
|
|
|
|
|
|
1444
|
|
|
|
|
|
|
=head3 warnings ( ) |
1445
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
Return a list of the warning messages (if any) that have been added to this |
1447
|
|
|
|
|
|
|
request. |
1448
|
|
|
|
|
|
|
|
1449
|
|
|
|
|
|
|
=head3 add_caution ( message ) |
1450
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
Add the specified caution message to this request. The caution messages will be automatically |
1452
|
|
|
|
|
|
|
included in the result, in a manner appropriate for the selected response format. |
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
=head3 cautions ( ) |
1455
|
|
|
|
|
|
|
|
1456
|
|
|
|
|
|
|
Return a list of the caution messages (if any) that have been added to this request. |
1457
|
|
|
|
|
|
|
|
1458
|
|
|
|
|
|
|
=head3 add_error ( message ) |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
Add the specified error message to this request. The error messages will be automatically |
1461
|
|
|
|
|
|
|
included in the result, in a manner appropriate for the selected response format. |
1462
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
=head3 errors ( ) |
1464
|
|
|
|
|
|
|
|
1465
|
|
|
|
|
|
|
Return a list of the error messages (if any) that have been added to this request. |
1466
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
=head1 AUTHOR |
1468
|
|
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
mmcclenn "at" cpan.org |
1470
|
|
|
|
|
|
|
|
1471
|
|
|
|
|
|
|
=head1 BUGS |
1472
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
1474
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
1475
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
1476
|
|
|
|
|
|
|
|
1477
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
1478
|
|
|
|
|
|
|
|
1479
|
|
|
|
|
|
|
Copyright 2014 Michael McClennen, all rights reserved. |
1480
|
|
|
|
|
|
|
|
1481
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
1482
|
|
|
|
|
|
|
under the same terms as Perl itself. |
1483
|
|
|
|
|
|
|
|
1484
|
|
|
|
|
|
|
=cut |
1485
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
1; |