Browse Source

Bug 17932: Add a TO_JSON method to Koha::Object(s)

Bug 17927 fixes data types on the current REST endpoints. If you
test those endpoints, you will notice trying to access them (for listing
or retrieving single objects yields a data type error. Notably on
booleans but also on integers.

Integers fail due to https://rt.cpan.org/Ticket/Display.html?id=119904
but it needs some global solution until there's a DBD::mysql release
backported to the supported distros. There's the option to use
http://search.cpan.org/~frew/DBIx-Class-Helpers-2.033002/lib/DBIx/Class/Helper/Row/NumifyGet.pm
to get the integer columns fixed as a workaround:

 __PACKAGE__->add_columns(
    borrowernumber => {
        data_type         => 'integer',
        is_nullable       => 0,
        is_numeric        => 1,
    }
);

I didn't find bug reports related to this (maybe because we don't use
warnings everywhere) But I don't think is worth going such a heavy
overhead.

A similar situation takes place for Boolean values. They need to be
prepared for JSON output. This could have been done using DBIx filters
as pointed out by Martin:

__PACKAGE__->filter_column(
    lost => {
       filter_to_storage => sub { $_[1] ? 1 : 0 },
       filter_from_storage =>
               sub { $_[1] ? Mojo::JSON->true :
                             Mojo::JSON->false }
       }
);

but this could have other consequences that are worth exploring on
another bug (i.e. it would mean we need to take care of every place
where this boolean data is used/set needs to handle this data types
nicely. Such would be the case if we were a Mojo-only app, but we
aren't. We use Koha::Obect(s) in the whole app. Period.

This patch adds the need to specify on the schema files, columns that
are actually boolean, because we have no way to detect them for now
(i.e. they are all tinyint, but we use tinyint for non-boolean stuff
 too).
So if this patch is accepted, we would need to specify boolean columns
like this:

__PACKAGE__->add_columns(
    '+lost' => {
        is_boolean => 1
    }
);

This patch adds a TO_JSON method for Koha::Object(s) to be used for
serializing Koha::Object-derived objects into JSON strings.

To test it (as Koha::Object(s) need to be instantiated) I provide tests
on top of the Koha::Patron(s) classes in the followup patches.

[1] Yes, we use TINYINT(1) for booleans, but from DBIC's perspective
there's no way to read the (1) in runtime.

Sponsored-by: ByWater Solutions

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
17.05.x
Tomás Cohen Arazi 7 years ago
committed by Kyle M Hall
parent
commit
51f62ccb30
  1. 56
      Koha/Object.pm
  2. 12
      Koha/Objects.pm

56
Koha/Object.pm

@ -21,6 +21,7 @@ package Koha::Object;
use Modern::Perl;
use Carp;
use Mojo::JSON;
use Koha::Database;
use Koha::Exceptions::Object;
@ -190,6 +191,61 @@ sub unblessed {
return { $self->_result->get_columns };
}
=head3 $object->TO_JSON
Returns an unblessed representation of the object, suitable for JSON output.
=cut
sub TO_JSON {
my ($self) = @_;
my $unblessed = $self->unblessed;
my $columns_info = Koha::Database->new->schema->resultset( $self->_type )
->result_source->{_columns};
foreach my $col ( keys %{$columns_info} ) {
if ( $columns_info->{$col}->{is_boolean} )
{ # Handle booleans gracefully
$unblessed->{$col}
= ( $unblessed->{$col} )
? Mojo::JSON->true
: Mojo::JSON->false;
}
elsif ( _numeric_column_type( $columns_info->{$col}->{data_type} ) ) {
# TODO: Remove once the solution for
# https://rt.cpan.org/Ticket/Display.html?id=119904
# is ported to whatever distro we support by that time
$unblessed->{$col} += 0;
}
}
return $unblessed;
}
sub _numeric_column_type {
# TODO: Remove once the solution for
# https://rt.cpan.org/Ticket/Display.html?id=119904
# is ported to whatever distro we support by that time
my ($column_type) = @_;
my @numeric_types = (
'bigint',
'integer',
'int',
'mediumint',
'smallint',
'tinyint',
'decimal',
'double precision',
'float'
);
return ( grep { $column_type eq $_ } @numeric_types) ? 1 : 0;
}
=head3 $object->_result();
Returns the internal DBIC Row object

12
Koha/Objects.pm

@ -252,6 +252,18 @@ sub unblessed {
return [ map { $_->unblessed } $self->as_list ];
}
=head3 Koha::Objects->TO_JSON
Returns an unblessed representation of objects, suitable for JSON output.
=cut
sub TO_JSON {
my ($self) = @_;
return [ map { $_->TO_JSON } $self->as_list ];
}
=head3 Koha::Objects->_wrap
wraps the DBIC object in a corresponding Koha object

Loading…
Cancel
Save