View | Details | Raw Unified | Return to bug 21761
Collapse All | Expand All

(-)a/Koha/Object.pm (-25 / +98 lines)
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),
(-)a/t/db_dependent/Koha/Object.t (-1 / +3 lines)
Lines 345-350 subtest 'store() tests' => sub { Link Here
345
    is( $itemtype->notforloan, undef, 'int DEFAULT NULL should default to null');
345
    is( $itemtype->notforloan, undef, 'int DEFAULT NULL should default to null');
346
    is( $itemtype->hideinopac, 0, 'int NOT NULL DEFAULT 0 should default to 0');
346
    is( $itemtype->hideinopac, 0, 'int NOT NULL DEFAULT 0 should default to 0');
347
347
348
    $itemtype = $builder->build_object( { class => 'Koha::ItemTypes' });
349
    $itemtype->update({ notforloan => "" });
350
348
    subtest 'Bad value tests' => sub {
351
    subtest 'Bad value tests' => sub {
349
352
350
        plan tests => 1;
353
        plan tests => 1;
351
- 

Return to bug 21761