Skip to content

Commit

Permalink
Added JSONField role so that I could add validation everywhere.
Browse files Browse the repository at this point in the history
  • Loading branch information
rizen committed Nov 28, 2017
1 parent 3720fa3 commit 9c6487f
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This file tracks the changes to Wing over time. Especially
with respect to new features and compatibility changes. with respect to new features and compatibility changes.
========================================================== ==========================================================


2017-11-28
* Added JSONField role so that I could add validation everywhere.

2017-10-05 2017-10-05
* Should have written tests for the new check privilege stuff. * Should have written tests for the new check privilege stuff.


Expand Down
64 changes: 64 additions & 0 deletions lib/Wing/Role/Result/JSONField.pm
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,64 @@
package Wing::Role::Result::JSONField;

use Wing::Perl;
use Ouch;
use Moose::Role;
with 'Wing::Role::Result::Field';
use JSON;

=head1 NAME
Wing::Role::Result::JSONField - Inflate JSON into Perl data structures.
=head1 SYNOPSIS
with 'Wing::Role::Result::JSONField';
__PACKAGE__->wing_json_fields(
custom_fields => {},
);
=head1 DESCRIPTION
Using this role will allow you to inflate and deflate JSON blobs into Perl data structures automatically.
=cut

sub wing_json_fields {
my ($class, %fields) = @_;
while (my ($field, $definition) = each %fields) {
$class->wing_json_field($field, $definition);
}
}

sub wing_json_field {
my ($object_class, $field, $options) = @_;

my %dbic = ( data_type => 'mediumblob', is_nullable => 1, 'serializer_class' => 'JSON', 'serializer_options' => { utf8 => 1 } );
$options->{dbic} = \%dbic;
$object_class->wing_field($field, $options);

$object_class->meta->add_after_method_modifier(wing_apply_fields => sub {
my ($class) = @_;
$class->meta->add_around_method_modifier($field => sub {
if (scalar @_ == 3 && defined $_[2]) {
my ($orig, $self, $json) = @_;
my $perl = eval { from_json($json) };
if ($@) {
my $error = $@;
$error =~ m/^(.*)\sat\s.*/;
my $help = $1;
Wing->log->warn($field.': '. $error);
ouch 442, 'Invalid JSON for '.$field.': '.$help, $field;
}
else {
return $self->$orig($perl);
}
}
return $_[0]->($_[1]);
});
});

}

1;

0 comments on commit 9c6487f

Please sign in to comment.