|
Lines 118-154
Returns:
Link Here
|
| 118 |
|
118 |
|
| 119 |
=cut |
119 |
=cut |
| 120 |
|
120 |
|
| 121 |
sub store { |
121 |
sub _fix_default_value { |
| 122 |
my ($self) = @_; |
122 |
my ($self, $params) = @_; |
|
|
123 |
|
| 124 |
my $column_info = $params->{column_info}; |
| 125 |
my $col = $params->{col}; |
| 126 |
my $val = exists $params->{val} ? $params->{val} : $self->$col; |
| 127 |
|
| 128 |
return unless $column_info; # the column does not exist |
| 129 |
|
| 130 |
my $reset; |
| 131 |
# Integers |
| 132 |
if ( _numeric_column_type( $column_info->{data_type} ) ) { |
| 133 |
# Has been passed but not a number, usually an empty string |
| 134 |
if ( defined $val and not looks_like_number( $val ) ) { |
| 135 |
if ( $column_info->{is_nullable} ) { |
| 136 |
# If nullable, default to null |
| 137 |
$val = undef; |
| 138 |
$reset = 1; |
| 139 |
} else { |
| 140 |
# If cannot be null, get the default value |
| 141 |
# What if cannot be null and does not have a default value? Possible? |
| 142 |
$val = $column_info->{default_value}; |
| 143 |
$reset = 1; |
| 144 |
} |
| 145 |
} |
| 146 |
} |
| 147 |
elsif ( _date_or_datetime_column_type( $column_info->{data_type} ) ) { |
| 148 |
# Set to null if an empty string (or == 0 but should not happen) |
| 149 |
if ( defined $val and not $val ) { |
| 150 |
if ( $column_info->{is_nullable} ) { |
| 151 |
$val = undef; |
| 152 |
$reset = 1; |
| 153 |
} else { |
| 154 |
$val = $column_info->{default_value}; |
| 155 |
$reset = 1; |
| 156 |
} |
| 157 |
} |
| 158 |
} |
| 159 |
$self->$col($val) if $reset; |
| 160 |
return $reset; |
| 161 |
} |
| 123 |
|
162 |
|
| 124 |
my $columns_info = $self->_result->result_source->columns_info; |
163 |
sub update { |
|
|
164 |
my ($self, $values) = @_; |
| 125 |
|
165 |
|
| 126 |
# Handle not null and default values for integers and dates |
166 |
my $columns_info = $self->_result->result_source->columns_info; |
| 127 |
foreach my $col ( keys %{$columns_info} ) { |
167 |
my $new_values; |
| 128 |
# Integers |
168 |
for my $col ( keys %$values ) { |
| 129 |
if ( _numeric_column_type( $columns_info->{$col}->{data_type} ) ) { |
169 |
if ( |
| 130 |
# Has been passed but not a number, usually an empty string |
170 |
$self->_fix_default_value( |
| 131 |
if ( defined $self->$col and not looks_like_number( $self->$col ) ) { |
171 |
{ |
| 132 |
if ( $columns_info->{$col}->{is_nullable} ) { |
172 |
col => $col, |
| 133 |
# If nullable, default to null |
173 |
column_info => $columns_info->{$col}, |
| 134 |
$self->$col(undef); |
174 |
val => $values->{$col} |
| 135 |
} else { |
|
|
| 136 |
# If cannot be null, get the default value |
| 137 |
# What if cannot be null and does not have a default value? Possible? |
| 138 |
$self->$col($columns_info->{$col}->{default_value}); |
| 139 |
} |
175 |
} |
| 140 |
} |
176 |
) |
|
|
177 |
) |
| 178 |
{ |
| 179 |
$values->{$col} = $self->$col; |
| 141 |
} |
180 |
} |
| 142 |
elsif ( _date_or_datetime_column_type( $columns_info->{$col}->{data_type} ) ) { |
181 |
} |
| 143 |
# Set to null if an empty string (or == 0 but should not happen) |
182 |
try { |
| 144 |
if ( defined $self->$col and not $self->$col ) { |
183 |
return $self->_result->update($values) ? $self : undef; |
| 145 |
if ( $columns_info->{$col}->{is_nullable} ) { |
184 |
} |
| 146 |
$self->$col(undef); |
185 |
catch { |
| 147 |
} else { |
186 |
# FIXME this is copied from ->store |
| 148 |
$self->$col($columns_info->{$col}->{default_value}); |
187 |
|
|
|
188 |
# Catch problems and raise relevant exceptions |
| 189 |
if (ref($_) eq 'DBIx::Class::Exception') { |
| 190 |
if ( $_->{msg} =~ /Cannot add or update a child row: a foreign key constraint fails/ ) { |
| 191 |
# FK constraints |
| 192 |
# FIXME: MySQL error, if we support more DB engines we should implement this for each |
| 193 |
if ( $_->{msg} =~ /FOREIGN KEY \(`(?<column>.*?)`\)/ ) { |
| 194 |
Koha::Exceptions::Object::FKConstraint->throw( |
| 195 |
error => 'Broken FK constraint', |
| 196 |
broken_fk => $+{column} |
| 197 |
); |
| 149 |
} |
198 |
} |
| 150 |
} |
199 |
} |
|
|
200 |
elsif( $_->{msg} =~ /Duplicate entry '(.*?)' for key '(?<key>.*?)'/ ) { |
| 201 |
Koha::Exceptions::Object::DuplicateID->throw( |
| 202 |
error => 'Duplicate ID', |
| 203 |
duplicate_id => $+{key} |
| 204 |
); |
| 205 |
} |
| 206 |
elsif( $_->{msg} =~ /Incorrect (?<type>\w+) value: '(?<value>.*)' for column '(?<property>\w+)'/ ) { |
| 207 |
Koha::Exceptions::Object::BadValue->throw( |
| 208 |
type => $+{type}, |
| 209 |
value => $+{value}, |
| 210 |
property => $+{property} |
| 211 |
); |
| 212 |
} |
| 151 |
} |
213 |
} |
|
|
214 |
Koha::Exceptions::Object->throw( ref($self) . "::update generated this error: " . $@ ); |
| 215 |
} |
| 216 |
} |
| 217 |
|
| 218 |
sub store { |
| 219 |
my ($self) = @_; |
| 220 |
|
| 221 |
my $columns_info = $self->_result->result_source->columns_info; |
| 222 |
# Handle not null and default values for integers and dates |
| 223 |
foreach my $col ( keys %{$columns_info} ) { |
| 224 |
$self->_fix_default_value({ col => $col, column_info => $columns_info->{$col} }); |
| 152 |
} |
225 |
} |
| 153 |
|
226 |
|
| 154 |
try { |
227 |
try { |
|
Lines 452-458
sub AUTOLOAD {
Link Here
|
| 452 |
} |
525 |
} |
| 453 |
} |
526 |
} |
| 454 |
|
527 |
|
| 455 |
my @known_methods = qw( is_changed id in_storage get_column discard_changes update make_column_dirty ); |
528 |
my @known_methods = qw( is_changed id in_storage get_column discard_changes make_column_dirty ); |
| 456 |
|
529 |
|
| 457 |
Koha::Exceptions::Object::MethodNotCoveredByTests->throw( |
530 |
Koha::Exceptions::Object::MethodNotCoveredByTests->throw( |
| 458 |
error => sprintf("The method %s->%s is not covered by tests!", ref($self), $method), |
531 |
error => sprintf("The method %s->%s is not covered by tests!", ref($self), $method), |