File Coverage

blib/lib/AtteanX/Parser/SPARQLJSON.pm
Criterion Covered Total %
statement 56 66 84.8
branch 13 22 59.0
condition n/a
subroutine 12 12 100.0
pod 6 6 100.0
total 87 106 82.0


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             AtteanX::Parser::SPARQLJSON - SPARQL JSON Parser
4              
5             =head1 VERSION
6              
7             This document describes AtteanX::Parser::SPARQLJSON version 0.032
8              
9             =head1 SYNOPSIS
10              
11             use Attean;
12             my $parser = Attean->get_parser('SPARQLJSON')->new();
13             $parser->parse_list_from_io( $fh );
14              
15             =head1 DESCRIPTION
16              
17             ...
18              
19             =head1 ATTRIBUTES
20              
21             =over 4
22              
23             =item C<< canonical_media_type >>
24              
25             =item C<< media_types >>
26              
27             =item C<< file_extensions >>
28              
29             =back
30              
31             =head1 METHODS
32              
33             =over 4
34              
35             =cut
36              
37 4     4   12182 use v5.14;
  4         15  
38 4     4   22 use warnings;
  4         11  
  4         192  
39              
40             use Attean;
41 4     4   23 use Moo;
  4         10  
  4         28  
42 4     4   29 use JSON;
  4         10  
  4         33  
43 4     4   3785 use Encode qw(decode);
  4         29689  
  4         27  
44 4     4   525
  4         8  
  4         1943  
45              
46 1     1 1 705 return [qw(application/sparql-results+json)];
47             }
48            
49 4     4 1 12  
50             with 'Attean::API::ResultOrTermParser';
51             with 'Attean::API::Parser';
52 5     5 1 20 with 'Attean::API::AtOnceParser';
53              
54             =item C<< parse_list_from_io( $fh ) >>
55              
56             =cut
57              
58             my $self = shift;
59             my $io = shift;
60             my $data = do { local($/) = undef; <$io> };
61             return $self->parse_list_from_bytes($data);
62             }
63 1     1 1 63
64 1         2 =item C<< parse_list_from_bytes( $bytes ) >>
65 1         2  
  1         5  
  1         7  
66 1         3 =cut
67              
68             my $self = shift;
69             my $octets = shift;
70             my $json = decode('UTF-8', $octets, Encode::FB_CROAK);
71             my $data = from_json($json, {utf8 => 1});
72             my $head = $data->{head};
73             my $vars = $head->{vars};
74 2     2 1 4 my $res = $data->{results};
75 2         5 if (defined(my $bool = $data->{boolean})) {
76 2         19 return ($bool) ? Attean::Literal->true : Attean::Literal->false;
77 2         245 } elsif (my $binds = $res->{bindings}) {
78 2         105 my @results;
79 2         4 foreach my $b (@$binds) {
80 2         4 my %data;
81 2 50       12 foreach my $v (@$vars) {
    50          
82 0 0       0 if (defined(my $value = $b->{ $v })) {
83             $data{ $v } = $self->decode_node($value);
84 2         5 }
85 2         4 }
86 3         26 push(@results, Attean::Result->new( bindings => \%data ));
87 3         6 }
88 10 100       2834 return @results;
89 9         24 }
90             }
91            
92 3         53 =item C<< decode_node( \%value ) >>
93              
94 2         72 =cut
95              
96             my $self = shift;
97             my $value = shift;
98             my $type = $value->{type};
99             if ($type eq 'uri') {
100             my $data = $value->{value};
101             return $self->new_iri( value => $data );
102             } elsif ($type eq 'bnode') {
103 9     9 1 11 my $data = $value->{value};
104 9         13 return Attean::Blank->new( $data );
105 9         17 } elsif ($type eq 'literal') {
106 9 100       28 my $data = $value->{value};
    100          
    50          
    0          
    0          
107 3         6 if (my $lang = $value->{'xml:lang'}) {
108 3         12 return Attean::Literal->new( value => $data, language => $lang );
109             } elsif (my $dt = $value->{'datatype'}) {
110 2         5 my $iri = $self->new_iri(value => $dt);
111 2         35 return Attean::Literal->new( value => $data, datatype => $iri );
112             } else {
113 4         7 return Attean::Literal->new( $data );
114 4 100       15 }
    100          
115 2         28 } elsif ($type eq 'typed-literal') {
116             my $data = $value->{value};
117 1         8 my $dt = $value->{datatype};
118 1         179 my $iri = $self->new_iri(value => $dt);
119             return Attean::Literal->new( value => $data, datatype => $iri );
120 1         17 } elsif ($type eq 'triple') {
121             my $s = $self->decode_node($value->{value}{subject});
122             my $p = $self->decode_node($value->{value}{predicate});
123 0           my $o = $self->decode_node($value->{value}{object});
124 0           return Attean::Triple->new( $s, $p, $o );
125 0           } else {
126 0           die "Unknown node type $type during parsing of SPARQL JSON Results";
127             }
128 0           }
129 0            
130 0           }
131 0            
132              
133 0           1;
134              
135              
136             =back
137              
138             =head1 BUGS
139              
140             Please report any bugs or feature requests to through the GitHub web interface
141             at L<https://github.com/kasei/perlrdf/issues>.
142              
143             =head1 AUTHOR
144              
145             Gregory Todd Williams C<< <gwilliams@cpan.org> >>
146              
147             =head1 COPYRIGHT
148              
149             Copyright (c) 2014--2022 Gregory Todd Williams. This
150             program is free software; you can redistribute it and/or modify it under
151             the same terms as Perl itself.
152              
153             =cut