File Coverage

blib/lib/App/Dochazka/REST/Model/Activity.pm
Criterion Covered Total %
statement 36 68 52.9
branch 0 10 0.0
condition n/a
subroutine 12 20 60.0
pod 8 8 100.0
total 56 106 52.8


line stmt bran cond sub pod time code
1             # *************************************************************************
2             # Copyright (c) 2014-2017, SUSE LLC
3             #
4             # All rights reserved.
5             #
6             # Redistribution and use in source and binary forms, with or without
7             # modification, are permitted provided that the following conditions are met:
8             #
9             # 1. Redistributions of source code must retain the above copyright notice,
10             # this list of conditions and the following disclaimer.
11             #
12             # 2. Redistributions in binary form must reproduce the above copyright
13             # notice, this list of conditions and the following disclaimer in the
14             # documentation and/or other materials provided with the distribution.
15             #
16             # 3. Neither the name of SUSE LLC nor the names of its contributors may be
17             # used to endorse or promote products derived from this software without
18             # specific prior written permission.
19             #
20             # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21             # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22             # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23             # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24             # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25             # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26             # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27             # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28             # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29             # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30             # POSSIBILITY OF SUCH DAMAGE.
31             # *************************************************************************
32              
33             package App::Dochazka::REST::Model::Activity;
34              
35 41     41   62285 use 5.012;
  41         127  
36 41     41   173 use strict;
  41         76  
  41         642  
37 41     41   163 use warnings;
  41         85  
  41         943  
38 41     41   183 use App::CELL qw( $CELL $log $meta $site );
  41         113  
  41         3441  
39 41     41   1478 use App::Dochazka::REST::Model::Shared qw( cud load load_multiple priv_by_eid );
  41         74  
  41         1909  
40 41     41   1212 use DBI;
  41         12263  
  41         1275  
41 41     41   216 use Params::Validate qw{:all};
  41         75  
  41         4993  
42 41     41   240 use Try::Tiny;
  41         80  
  41         1785  
43              
44             # we get 'spawn', 'reset', and accessors from parent
45 41     41   229 use parent 'App::Dochazka::Common::Model::Activity';
  41         83  
  41         243  
46              
47              
48              
49              
50             =head1 NAME
51              
52             App::Dochazka::REST::Model::Activity - activity data model
53              
54              
55              
56              
57             =head1 SYNOPSIS
58              
59             use App::Dochazka::REST::Model::Activity;
60              
61             ...
62              
63              
64             =head1 DATA MODEL
65              
66             =head2 Activities in the database
67              
68              
69             CREATE TABLE activities (
70             aid serial PRIMARY KEY,
71             code varchar(32) UNIQUE NOT NULL,
72             long_desc text,
73             remark text
74             )
75              
76             Activity codes will always be in ALL CAPS thanks to a trigger (entitled
77             C<code_to_upper>) that runs the PostgreSQL C<upper> function on the code
78             before every INSERT and UPDATE on this table.
79              
80              
81              
82             =head2 Activities in the Perl API
83              
84             =over
85              
86             =item * constructor (L<spawn>)
87              
88             =item * basic accessors (L<aid>, L<code>, L<long_desc>, L<remark>)
89              
90             =item * L<reset> (recycles an existing object by setting it to desired state)
91              
92             =item * L<TO_JSON> (returns 'unblessed' version of an Activity object)
93              
94             =item * L<compare> (compare two objects)
95              
96             =item * L<clone> (clone an object)
97              
98             =item * L<insert> (inserts object into database)
99              
100             =item * L<update> (updates database to match the object)
101              
102             =item * L<delete> (deletes record from database if nothing references it)
103              
104             =item * L<load_by_aid> (loads a single activity into an object)
105              
106             =item * L<load_by_code> (loads a single activity into an object)
107              
108             =item * L<get_all_activities> (load all activities)
109              
110             =back
111              
112             L<App::Dochazka::REST::Model::Activity> also exports some convenience
113             functions:
114              
115             =over
116              
117             =item * L<aid_exists> (boolean function)
118              
119             =item * L<code_exists> (boolean function)
120              
121             =item * L<aid_by_code> (given a code, returns AID)
122              
123             =item * L<code_by_aid> (given an AID, return a code)
124              
125             =item * L<get_all_activities>
126              
127             =back
128              
129             For basic C<activity> object workflow, see the unit tests in
130             C<t/model/activity.t>.
131              
132              
133              
134             =head1 EXPORTS
135              
136             This module provides the following exports:
137              
138             =over
139              
140             =item C<aid_by_code> - function
141              
142             =back
143              
144             =cut
145              
146 41     41   68030 use Exporter qw( import );
  41         84  
  41         16654  
147             our @EXPORT_OK = qw(
148             aid_by_code
149             aid_exists
150             code_by_aid
151             code_exists
152             get_all_activities
153             );
154              
155              
156              
157              
158             =head1 METHODS
159              
160              
161             =head2 insert
162              
163             Instance method. Takes the object, as it is, and attempts to insert it into
164             the database. On success, overwrites object attributes with field values
165             actually inserted. Returns a status object.
166              
167             =cut
168              
169             sub insert {
170 0     0 1   my $self = shift;
171 0           my ( $context ) = validate_pos( @_, { type => HASHREF } );
172              
173             my $status = cud(
174             conn => $context->{'dbix_conn'},
175 0           eid => $context->{'current'}->{'eid'},
176             object => $self,
177             sql => $site->SQL_ACTIVITY_INSERT,
178             attrs => [ 'code', 'long_desc', 'remark' ],
179             );
180              
181 0           return $status;
182             }
183              
184              
185             =head2 update
186              
187             Instance method. Assuming that the object has been prepared, i.e. the AID
188             corresponds to the activity to be updated and the attributes have been
189             changed as desired, this function runs the actual UPDATE, hopefully
190             bringing the database into line with the object. Overwrites all the
191             object's attributes with the values actually written to the database.
192             Returns status object.
193              
194             =cut
195              
196             sub update {
197 0     0 1   my $self = shift;
198 0           my ( $context ) = validate_pos( @_, { type => HASHREF } );
199              
200 0 0         return $CELL->status_err( 'DOCHAZKA_MALFORMED_400' ) unless $self->{'aid'};
201              
202             my $status = cud(
203             conn => $context->{'dbix_conn'},
204 0           eid => $context->{'current'}->{'eid'},
205             object => $self,
206             sql => $site->SQL_ACTIVITY_UPDATE,
207             attrs => [ 'code', 'long_desc', 'remark', 'disabled', 'aid' ],
208             );
209              
210 0           return $status;
211             }
212              
213              
214             =head2 delete
215              
216             Instance method. Assuming the AID really corresponds to the activity to be
217             deleted, this method will execute the DELETE statement in the database. It
218             won't succeed if the activity has any intervals associated with it. Returns
219             a status object.
220              
221             =cut
222              
223             sub delete {
224 0     0 1   my $self = shift;
225 0           my ( $context ) = validate_pos( @_, { type => HASHREF } );
226              
227             my $status = cud(
228             conn => $context->{'dbix_conn'},
229 0           eid => $context->{'current'}->{'eid'},
230             object => $self,
231             sql => $site->SQL_ACTIVITY_DELETE,
232             attrs => [ 'aid' ],
233             );
234 0 0         $self->reset( aid => $self->{aid} ) if $status->ok;
235              
236 0           return $status;
237             }
238              
239              
240             =head2 load_by_aid
241              
242             Loads activity from database, by the AID provided in the argument list,
243             into a newly-spawned object. The code must be an exact match. Returns a
244             status object: if the object is loaded, the code will be
245             'DISPATCH_RECORDS_FOUND' and the object will be in the payload; if
246             the AID is not found in the database, the code will be
247             'DISPATCH_NO_RECORDS_FOUND'. A non-OK status indicates a DBI error.
248              
249             =cut
250              
251             sub load_by_aid {
252 0     0 1   my $self = shift;
253 0           my ( $conn, $aid ) = validate_pos( @_,
254             { isa => 'DBIx::Connector' },
255             { type => SCALAR },
256             );
257              
258 0           return load(
259             conn => $conn,
260             class => __PACKAGE__,
261             sql => $site->SQL_ACTIVITY_SELECT_BY_AID,
262             keys => [ $aid ],
263             );
264             }
265              
266              
267             =head2 load_by_code
268              
269             Analogous method to L<"load_by_aid">.
270              
271             =cut
272              
273             sub load_by_code {
274 0     0 1   my $self = shift;
275 0           my ( $conn, $code ) = validate_pos( @_,
276             { isa => 'DBIx::Connector' },
277             { type => SCALAR },
278             );
279              
280 0           return load(
281             conn => $conn,
282             class => __PACKAGE__,
283             sql => $site->SQL_ACTIVITY_SELECT_BY_CODE,
284             keys => [ $code ],
285             );
286             }
287              
288              
289              
290              
291             =head1 FUNCTIONS
292              
293             The following functions are not object methods.
294              
295              
296             =head2 aid_exists
297              
298             Boolean function
299              
300              
301             =head2 code_exists
302              
303             Boolean function
304              
305             =cut
306              
307             BEGIN {
308 41     41   265 no strict 'refs';
  41         89  
  41         1821  
309 41     41   203 *{'aid_exists'} = App::Dochazka::REST::Model::Shared::make_test_exists( 'aid' );
  41         183  
310 41         133 *{'code_exists'} = App::Dochazka::REST::Model::Shared::make_test_exists( 'code' );
  41         8778  
311             }
312              
313              
314             =head2 aid_by_code
315              
316             Given a code, attempt to retrieve the corresponding AID.
317             Returns AID or undef on failure.
318              
319             =cut
320              
321             sub aid_by_code {
322 0     0 1   my ( $conn, $code ) = validate_pos( @_,
323             { isa => 'DBIx::Connector' },
324             { type => SCALAR },
325             );
326              
327 0           my $status = __PACKAGE__->load_by_code( $conn, $code );
328 0 0         return $status->payload->{'aid'} if $status->code eq 'DISPATCH_RECORDS_FOUND';
329 0           return;
330             }
331              
332              
333             =head2 code_by_aid
334              
335             Given an AID, attempt to retrieve the corresponding code.
336             Returns code or undef on failure.
337              
338             =cut
339              
340             sub code_by_aid {
341 0     0 1   my ( $conn, $aid ) = validate_pos( @_,
342             { isa => 'DBIx::Connector' },
343             { type => SCALAR },
344             );
345              
346 0           my $status = __PACKAGE__->load_by_aid( $conn, $aid );
347 0 0         return $status->payload->{'code'} if $status->code eq 'DISPATCH_RECORDS_FOUND';
348 0           return;
349             }
350              
351              
352             =head2 get_all_activities
353              
354             Optionally takes a PARAMHASH that can contain a 'disabled' key which can be
355             either true or false (defaults to false).
356              
357             Returns a reference to a hash of hashes, where each hash is one activity object.
358             If 'disabled' is true, all activities including disabled ones will be included,
359             otherwise only the non-disabled activities will be retrieved.
360              
361             =cut
362              
363             sub get_all_activities {
364 0     0 1   my $conn = shift;
365 0           my %PH = validate( @_, {
366             disabled => { type => SCALAR, default => 0 }
367             } );
368            
369             my $sql = $PH{disabled}
370 0 0         ? $site->SQL_ACTIVITY_SELECT_ALL_INCLUDING_DISABLED
371             : $site->SQL_ACTIVITY_SELECT_ALL_EXCEPT_DISABLED;
372              
373 0           return load_multiple(
374             conn => $conn,
375             class => __PACKAGE__,
376             sql => $sql,
377             keys => [],
378             );
379             }
380              
381              
382              
383              
384             =head1 AUTHOR
385              
386             Nathan Cutler, C<< <presnypreklad@gmail.com> >>
387              
388             =cut
389              
390             1;
391