| 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::Schedintvls; | 
| 34 |  |  |  |  |  |  |  | 
| 35 | 41 |  |  | 41 |  | 1656 | use 5.012; | 
|  | 41 |  |  |  |  | 159 |  | 
| 36 | 41 |  |  | 41 |  | 240 | use strict; | 
|  | 41 |  |  |  |  | 91 |  | 
|  | 41 |  |  |  |  | 839 |  | 
| 37 | 41 |  |  | 41 |  | 216 | use warnings; | 
|  | 41 |  |  |  |  | 93 |  | 
|  | 41 |  |  |  |  | 1157 |  | 
| 38 | 41 |  |  | 41 |  | 230 | use App::CELL qw( $CELL $log $meta $site ); | 
|  | 41 |  |  |  |  | 97 |  | 
|  | 41 |  |  |  |  | 4603 |  | 
| 39 | 41 |  |  | 41 |  | 357 | use App::Dochazka::REST::ConnBank qw( $dbix_conn ); | 
|  | 41 |  |  |  |  | 126 |  | 
|  | 41 |  |  |  |  | 3725 |  | 
| 40 | 41 |  |  | 41 |  | 320 | use App::Dochazka::REST::Model::Shared; | 
|  | 41 |  |  |  |  | 108 |  | 
|  | 41 |  |  |  |  | 1590 |  | 
| 41 | 41 |  |  | 41 |  | 275 | use Data::Dumper; | 
|  | 41 |  |  |  |  | 127 |  | 
|  | 41 |  |  |  |  | 1832 |  | 
| 42 | 41 |  |  | 41 |  | 279 | use JSON; | 
|  | 41 |  |  |  |  | 92 |  | 
|  | 41 |  |  |  |  | 317 |  | 
| 43 | 41 |  |  | 41 |  | 4468 | use Params::Validate qw( :all ); | 
|  | 41 |  |  |  |  | 97 |  | 
|  | 41 |  |  |  |  | 6031 |  | 
| 44 | 41 |  |  | 41 |  | 329 | use Try::Tiny; | 
|  | 41 |  |  |  |  | 142 |  | 
|  | 41 |  |  |  |  | 2193 |  | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | # we get 'spawn', 'reset', and accessors from parent | 
| 47 | 41 |  |  | 41 |  | 293 | use parent 'App::Dochazka::Common::Model::Schedintvls'; | 
|  | 41 |  |  |  |  | 99 |  | 
|  | 41 |  |  |  |  | 303 |  | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | =head1 NAME | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | App::Dochazka::REST::Model::Schedintvls - object class for "scratch schedules" | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | use App::Dochazka::REST::Model::Schedintvls; | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | ... | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | =head1 METHODS | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | =head2 populate | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | Populate the schedintvls object (called automatically by 'reset' method | 
| 74 |  |  |  |  |  |  | which is, in turn, called automatically by 'spawn') | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | =cut | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | sub populate { | 
| 79 | 0 |  |  | 0 | 1 |  | my $self = shift; | 
| 80 |  |  |  |  |  |  |  | 
| 81 | 0 |  |  |  |  |  | my $ss = _next_scratch_sid(); | 
| 82 | 0 |  |  |  |  |  | $log->debug( "Got next scratch SID: $ss" ); | 
| 83 | 0 |  |  |  |  |  | $self->{'ssid'} = $ss; | 
| 84 | 0 |  |  |  |  |  | return; | 
| 85 |  |  |  |  |  |  | } | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | =head2 load | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | Instance method. Once the scratch intervals are inserted, we have a fully | 
| 91 |  |  |  |  |  |  | populated object. This method runs each scratch interval through the stored | 
| 92 |  |  |  |  |  |  | procedure 'translate_schedintvl' -- upon success, it creates a new attribute, | 
| 93 |  |  |  |  |  |  | C<< $self->{schedule} >>, containing the translated intervals. | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | =cut | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | sub load { | 
| 98 | 0 |  |  | 0 | 1 |  | my $self = shift; | 
| 99 | 0 |  |  |  |  |  | my ( $conn ) = validate_pos( @_, | 
| 100 |  |  |  |  |  |  | { isa => 'DBIx::Connector' } | 
| 101 |  |  |  |  |  |  | ); | 
| 102 |  |  |  |  |  |  |  | 
| 103 | 0 |  |  |  |  |  | my $status; | 
| 104 |  |  |  |  |  |  | my @results; | 
| 105 |  |  |  |  |  |  | try { | 
| 106 |  |  |  |  |  |  | $conn->run( fixup => sub { | 
| 107 |  |  |  |  |  |  | # prepare and execute statement | 
| 108 | 0 |  |  |  |  |  | my $sth = $_->prepare( $site->SQL_SCHEDINTVLS_SELECT ); | 
| 109 | 0 |  |  |  |  |  | $sth->execute( $self->{'ssid'} ); | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | # since the statement returns n rows, we use a loop to fetch them | 
| 112 | 0 |  |  |  |  |  | while( defined( my $tmpres = $sth->fetchrow_hashref() ) ) { | 
| 113 | 0 |  |  |  |  |  | push( @results, $tmpres ); | 
| 114 |  |  |  |  |  |  | } | 
| 115 | 0 |  |  | 0 |  |  | } ); | 
| 116 |  |  |  |  |  |  | } catch { | 
| 117 | 0 |  |  | 0 |  |  | $status = $CELL->status_err( 'DOCHAZKA_DBI_ERR', args => [ $_ ] ); | 
| 118 | 0 |  |  |  |  |  | }; | 
| 119 | 0 | 0 |  |  |  |  | return $status if $status; | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | # success: add a new attribute with the translated intervals | 
| 122 | 0 |  |  |  |  |  | $self->{schedule} = \@results; | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 0 |  |  |  |  |  | return $CELL->status_ok( "Schedule has " . scalar( @results ) . " rows" ); | 
| 125 |  |  |  |  |  |  | } | 
| 126 |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | =head2 insert | 
| 130 |  |  |  |  |  |  |  | 
| 131 |  |  |  |  |  |  | Instance method. Attempts to INSERT one or more records (one for each | 
| 132 |  |  |  |  |  |  | interval in the 'intvls' attribute) into the 'schedintvls' table. | 
| 133 |  |  |  |  |  |  | Field values are taken from the object. Returns a status object. | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | =cut | 
| 136 |  |  |  |  |  |  |  | 
| 137 |  |  |  |  |  |  | sub insert { | 
| 138 | 0 |  |  | 0 | 1 |  | my $self = shift; | 
| 139 | 0 |  |  |  |  |  | my ( $conn ) = validate_pos( @_, | 
| 140 |  |  |  |  |  |  | { isa => 'DBIx::Connector' } | 
| 141 |  |  |  |  |  |  | ); | 
| 142 |  |  |  |  |  |  |  | 
| 143 |  |  |  |  |  |  | # the insert operation needs to take place within a transaction, | 
| 144 |  |  |  |  |  |  | # because all the intervals are inserted in one go | 
| 145 | 0 |  |  |  |  |  | my $status; | 
| 146 |  |  |  |  |  |  | try { | 
| 147 |  |  |  |  |  |  | $conn->txn( fixup => sub { | 
| 148 | 0 |  |  |  |  |  | my $sth = $_->prepare( $site->SQL_SCHEDINTVLS_INSERT ); | 
| 149 | 0 |  |  |  |  |  | my $intvls; | 
| 150 |  |  |  |  |  |  |  | 
| 151 |  |  |  |  |  |  | # the next sequence value is already in $self->{ssid} | 
| 152 | 0 |  |  |  |  |  | $sth->bind_param( 1, $self->{ssid} ); | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | # execute SQL_SCHEDINTVLS_INSERT for each element of $self->{intvls} | 
| 155 |  |  |  |  |  |  | map { | 
| 156 | 0 |  |  |  |  |  | $sth->bind_param( 2, $_ ); | 
| 157 | 0 |  |  |  |  |  | $sth->execute; | 
| 158 | 0 |  |  |  |  |  | push @$intvls, $_; | 
| 159 | 0 |  |  |  |  |  | } @{ $self->{intvls} }; | 
|  | 0 |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | $status = $CELL->status_ok( | 
| 161 |  |  |  |  |  |  | 'DOCHAZKA_SCHEDINTVLS_INSERT_OK', | 
| 162 |  |  |  |  |  |  | payload => { | 
| 163 |  |  |  |  |  |  | intervals => $intvls, | 
| 164 |  |  |  |  |  |  | ssid => $self->{ssid}, | 
| 165 |  |  |  |  |  |  | } | 
| 166 | 0 |  |  |  |  |  | ); | 
| 167 | 0 |  |  | 0 |  |  | } ); | 
| 168 |  |  |  |  |  |  | } catch { | 
| 169 | 0 |  |  | 0 |  |  | $status = $CELL->status_err( 'DOCHAZKA_DBI_ERR', args => [ $_ ] ); | 
| 170 | 0 |  |  |  |  |  | }; | 
| 171 | 0 |  |  |  |  |  | return $status; | 
| 172 |  |  |  |  |  |  | } | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | =head2 update | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | There is no update method for schedintvls. Instead, delete and re-create. | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | =head2 delete | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | Instance method. Once we are done with the scratch intervals, they can be deleted. | 
| 183 |  |  |  |  |  |  | Returns a status object. | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | =cut | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | sub delete { | 
| 188 | 0 |  |  | 0 | 1 |  | my $self = shift; | 
| 189 | 0 |  |  |  |  |  | my ( $conn ) = validate_pos( @_, | 
| 190 |  |  |  |  |  |  | { isa => 'DBIx::Connector' } | 
| 191 |  |  |  |  |  |  | ); | 
| 192 |  |  |  |  |  |  |  | 
| 193 | 0 |  |  |  |  |  | my $status; | 
| 194 |  |  |  |  |  |  | try { | 
| 195 |  |  |  |  |  |  | $conn->run( fixup => sub { | 
| 196 | 0 |  |  |  |  |  | my $sth = $_->prepare( $site->SQL_SCHEDINTVLS_DELETE ); | 
| 197 | 0 |  |  |  |  |  | $sth->bind_param( 1, $self->ssid ); | 
| 198 | 0 |  |  |  |  |  | $sth->execute; | 
| 199 | 0 |  |  |  |  |  | my $rows = $sth->rows; | 
| 200 | 0 | 0 |  |  |  |  | if ( $rows > 0 ) { | 
|  |  | 0 |  |  |  |  |  | 
| 201 | 0 |  |  |  |  |  | $status = $CELL->status_ok( 'DOCHAZKA_RECORDS_DELETED', args => [ $rows ] ); | 
| 202 |  |  |  |  |  |  | } elsif ( $rows == 0 ) { | 
| 203 | 0 |  |  |  |  |  | $status = $CELL->status_warn( 'DOCHAZKA_RECORDS_DELETED', args => [ $rows ] ); | 
| 204 |  |  |  |  |  |  | } else { | 
| 205 | 0 |  |  |  |  |  | die( "\$sth->rows returned a weird value $rows" ); | 
| 206 |  |  |  |  |  |  | } | 
| 207 | 0 |  |  | 0 |  |  | } ); | 
| 208 |  |  |  |  |  |  | } catch { | 
| 209 | 0 |  |  | 0 |  |  | $status = $CELL->status_err( 'DOCHAZKA_DBI_ERR', args => [ $_ ] ); | 
| 210 | 0 |  |  |  |  |  | }; | 
| 211 | 0 |  |  |  |  |  | return $status; | 
| 212 |  |  |  |  |  |  | } | 
| 213 |  |  |  |  |  |  |  | 
| 214 |  |  |  |  |  |  |  | 
| 215 |  |  |  |  |  |  | =head2 json | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | Instance method. Returns a JSON string representation of the schedule. | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | =cut | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | sub json { | 
| 222 | 0 |  |  | 0 | 1 |  | my ( $self ) = @_; | 
| 223 |  |  |  |  |  |  |  | 
| 224 | 0 |  |  |  |  |  | return JSON->new->utf8->canonical(1)->encode( $self->{schedule} ); | 
| 225 |  |  |  |  |  |  | } | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  |  | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | =head2 Exported functions | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  |  | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | =head2 Non-exported functions | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | =head3 _next_scratch_sid | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | Get next value from the scratch_sid_seq sequence | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | =cut | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | sub _next_scratch_sid { | 
| 245 | 0 |  |  | 0 |  |  | my $val; | 
| 246 |  |  |  |  |  |  | my $status; | 
| 247 |  |  |  |  |  |  | try { | 
| 248 |  |  |  |  |  |  | $dbix_conn->run( fixup => sub { | 
| 249 | 0 |  |  |  |  |  | ( $val ) = $_->selectrow_array( $site->SQL_SCRATCH_SID ); | 
| 250 | 0 |  |  | 0 |  |  | } ); | 
| 251 |  |  |  |  |  |  | } catch { | 
| 252 | 0 |  |  | 0 |  |  | $status = $CELL->status_err( 'DOCHAZKA_DBI_ERR', args => [ $_ ] ); | 
| 253 | 0 |  |  |  |  |  | }; | 
| 254 | 0 | 0 |  |  |  |  | return if $status; | 
| 255 | 0 |  |  |  |  |  | return $val; | 
| 256 |  |  |  |  |  |  | } | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  |  | 
| 260 |  |  |  |  |  |  | =head1 AUTHOR | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | Nathan Cutler, C<< <presnypreklad@gmail.com> >> | 
| 263 |  |  |  |  |  |  |  | 
| 264 |  |  |  |  |  |  | =cut | 
| 265 |  |  |  |  |  |  |  | 
| 266 |  |  |  |  |  |  | 1; | 
| 267 |  |  |  |  |  |  |  |