1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
package Catmandu::Fix::aref_query;
use Catmandu::Sane;
use Moo;
use Catmandu::Fix;
our $VERSION = '0.32';
with 'Catmandu::Fix::Base';
has query => (
is => 'ro',
coerce => sub { RDF::aREF::Query->new( query => $_[0] ) } # TODO: ns
);
has path => (
is => 'ro',
);
has subject => (
is => 'ro',
);
around 'BUILDARGS', sub {
my $orig = shift;
my $self = shift;
if (@_ == 3) {
$orig->($self, subject => $_[0], query => $_[1], path => $_[2] );
} elsif (@_ == 2) {
$orig->($self, query => $_[0], path => $_[1] );
} else {
$orig->($self, @_);
}
};
sub emit {
my ($self, $fixer) = @_;
my $subject = defined $self->subject ? $fixer->emit_string($self->subject) : 'undef';
my $path = $fixer->split_path($self->path);
my $query = $fixer->capture($self->query);
# TODO: replace/append/single-value mode
my $var = $fixer->var;
my $origin = $fixer->generate_var;
my $values = $fixer->generate_var;
my $perl = join "\n",
"my ${origin} = ${subject} // ${var}->{_uri} // ${var}->{_url};",
"my ${values} = [ ${query}->apply( ${var}, ${origin} ) ];",
$fixer->emit_create_path( $var, $path, sub {
my $var = shift;
join "\n", map { " $_" } '',
"if (is_array_ref(${var})) {",
" push \@{${var}}, \@{${values}};",
"} else {",
" if (defined ${var}) {",
" unshift \@{${values}}, ${var};",
" }",
" ${var} = \@{${values}} > 1 ? ${values} : ${values}->[0];",
"}"
;
});
# print $perl."\n";
return $perl;
}
1;
__END__
=head1 NAME
Catmandu::Fix::aref_query - copy values of RDF in aREF to a new field
=head1 SYNOPSIS
In Catmandu Fix language
aref_query( dc_title => title )
aref_query( query => 'dc_title', field => 'title' )
aref_query( 'http://example.org/subject', dc_title => title )
In Perl code
use Catmandu::Fix::aref_query as => 'my_query';
use RDF::aREF;
my $rdf = encode_aref("example.ttl");
my_query( $rdf, dc_title => 'title' );
=head1 DESCRIPTION
This L<Catmandu::Fix> can be used to map values of imported RDF, given in
L<aREF|http://gbv.github.io/aREF/> structure
=head1 ARGUMENTS
=over
=item subject
Optional subject URI (first argument). By default, the fields C<_uri> and
C<_uri> are used.
=item query
aREF query expression (first or second argument)
=item path
Field name to map RDF data to (last argument). Existing values are also kept.
=back
=head1 SEE ALSO
Function C<aref_query> in L<RDF::aREF>
=cut
|