AtteanX-Store-SPARQL
view release on metacpan or search on metacpan
NAME
AtteanX::Store::SPARQL - Attean SPARQL store
SYNOPSIS
my $store = Attean->get_store('SPARQL')->new(endpoint_url => $url);
DESCRIPTION
This implements a simple immutable triple store, which simply allows
programmers to use Attean facilities to query remote SPARQL endpoints.
This distribution also brings a corresponding AtteanX::Model::SPARQL,
which allows query plans to be made, and a AtteanX::Plan::SPARQLBGP plan
class, which contains a rudimentary cost estimate that attempts to avoid
sending Cartesian joins to remote endpoints if possible.
Attributes and methods
`endpoint_url`
The URL of a remote SPARQL endpoint. Will be coerced into a URI
object, so it may be set as a string or whatever. Required attribute.
`ua`
An LWP::UserAgent object to use for remote queries. Will be set to a
reasonable default if not supplied.
`get_triples`
Method to query the remote endpoint, as required by
Attean::API::TripleStore.
`count_triples`
Reimplemented using an aggregate query for greater efficiency.
`get_sparql($sparql, [ $ua ])`
Will submit the given $sparql query to the above `endpoint_url`
attribute. Optionally, you may pass an LWP::UserAgent, if not it will
use the user agent set using the `ua` method. Will return an iterator
with the results if the request is successful.
BUGS
Please report any bugs to
<https://github.com/kjetilk/p5-atteanx-store-sparql/issues>.
ACKNOWLEDGEMENTS
This module is heavily influenced by RDF::Trine::Store::SPARQL.
lib/AtteanX/Model/SPARQL.pm view on Meta::CPAN
=pod
=encoding utf-8
=head1 NAME
AtteanX::Model::SPARQL - Attean SPARQL Model
=head1 SYNOPSIS
my $store = Attean->get_store('SPARQL')->new(endpoint_url => $url);
my $model = AtteanX::Model::SPARQL->new( store => $store );
=head1 DESCRIPTION
This model is in practice a thin wrapper around the underlying SPARQL
store, that adds facilities only to allow quering and planning with
quad semantics.
It consumes L<Attean::API::Model> and L<Attean::API::CostPlanner> and
adds no new methods or attributes.
lib/AtteanX/Plan/SPARQLBGP.pm view on Meta::CPAN
=head1 NAME
AtteanX::Plan::SPARQLBGP - Plan for efficient evaluation of SPARQL BGPs on remote endpoints
=head1 SYNOPSIS
This is typically only constructed by planning hacks deep in the code,
but might look like:
use v5.14;
use AtteanX::Plan::SPARQLBGP;
my $new_bgp_plan = AtteanX::Plan::SPARQLBGP->new(children => [$some_quads],
distinct => 0,
ordered => []);
=head1 DESCRIPTION
This plan class implements compiling basic graph patterns that can be
joined remotely on a SPARQL endpoint.
=head2 Attributes and methods
Consumes L<Attean::API::QueryTree>, L<Attean::API::Plan> and
L<Attean::API::UnionScopeVariablesPlan>, and introduces nothing
new. The most notable attribute is:
=over
=item C<< children >>
lib/AtteanX/Store/SPARQL.pm view on Meta::CPAN
use Attean::RDF;
use AtteanX::Plan::SPARQLBGP;
use LWP::UserAgent;
use Data::Dumper;
use Carp;
with 'Attean::API::TripleStore';
with 'MooX::Log::Any';
has 'endpoint_url' => (is => 'ro', isa => Uri, coerce => 1);
has 'ua' => (is => 'rw', isa => InstanceOf['LWP::UserAgent'], builder => '_build_ua');
sub _build_ua {
my $self = shift;
my $ua = LWP::UserAgent->new;
$ua->default_headers->push_header( 'Accept' => 'application/sparql-results+json' ); #Attean->acceptable_parsers(handles => q[Attean::API::Result]));
return $ua;
}
sub get_triples {
lib/AtteanX/Store/SPARQL.pm view on Meta::CPAN
my $self = shift;
my $pattern = Attean::TriplePattern->new(@_);
my $iter = $self->get_sparql("SELECT (count(*) AS ?count) WHERE {\n\t".$pattern->tuples_string."\n}");
return $iter->next->value('count')->value;
}
sub get_sparql {
my $self = shift;
my $sparql = shift;
my $ua = shift || $self->ua;
my $url = $self->endpoint_url->clone;
my %query = $url->query_form;
$query{'query'} = $sparql;
$url->query_form(%query);
$self->log->debug('Sending GET request for URL: ' . $url);
my $response = $ua->get( $url );
if ($response->is_success) {
my $parsertype = Attean->get_parser( media_type => $response->content_type);
croak 'Could not parse response from '. $self->endpoint_url->as_string . ' which returned ' . $response->content_type unless defined($parsertype);
my $p = $parsertype->new;
return $p->parse_iter_from_bytes($response->content);
} else {
$self->log->trace('Got an error, dumping the response: ' . Dumper($response));
croak 'Error making remote SPARQL call to endpoint ' . $self->endpoint_url->as_string . ' (' .$response->status_line. ')';
}
}
sub plans_for_algebra {
my $self = shift;
my $algebra = shift;
my $model = shift;
my $active_graphs = shift;
my $default_graphs = shift;
lib/AtteanX/Store/SPARQL.pm view on Meta::CPAN
=pod
=encoding utf-8
=head1 NAME
AtteanX::Store::SPARQL - Attean SPARQL store
=head1 SYNOPSIS
my $store = Attean->get_store('SPARQL')->new(endpoint_url => $url);
=head1 DESCRIPTION
This implements a simple immutable triple store, which simply allows
programmers to use L<Attean> facilities to query remote SPARQL
endpoints.
This distribution also brings a corresponding
L<AtteanX::Model::SPARQL>, which allows query plans to be made, and a
L<AtteanX::Plan::SPARQLBGP> plan class, which contains a
rudimentary cost estimate that attempts to avoid sending Cartesian
joins to remote endpoints if possible.
=head2 Attributes and methods
=over
=item C<< endpoint_url >>
The URL of a remote SPARQL endpoint. Will be coerced into a L<URI>
object, so it may be set as a string or whatever. Required attribute.
=item C<< ua >>
An L<LWP::UserAgent> object to use for remote queries. Will be set to
a reasonable default if not supplied.
=item C<< get_triples >>
Method to query the remote endpoint, as required by L<Attean::API::TripleStore>.
=item C<< count_triples >>
Reimplemented using an aggregate query for greater efficiency.
=item C<< get_sparql($sparql, [ $ua ]) >>
Will submit the given C<$sparql> query to the above C<endpoint_url>
attribute. Optionally, you may pass an L<LWP::UserAgent>, if not it
will use the user agent set using the C<ua> method. Will return an
iterator with the results if the request is successful.
=back
lib/Test/Attean/Store/SPARQL/Role/CreateStore.pm view on Meta::CPAN
use RDF::Trine qw(statement iri blank literal);
use RDF::Endpoint;
use Test::LWP::UserAgent;
use HTTP::Message::PSGI;
use Moo::Role;
sub create_store {
my $self = shift;
my %args = @_;
my $triples = $args{triples} // [];
my $model = RDF::Trine::Model->temporary_model; # For creating endpoint
foreach my $atteantriple (@{$triples}) {
my $s = iri($atteantriple->subject->value);
if ($atteantriple->subject->is_blank) {
$s = blank($atteantriple->subject->value);
}
my $p = iri($atteantriple->predicate->value);
my $o = iri($atteantriple->object->value);
if ($atteantriple->object->is_literal) {
# difference with RDF 1.0 vs RDF 1.1 datatype semantics
if ($atteantriple->object->datatype->value eq 'http://www.w3.org/2001/XMLSchema#string') {
lib/Test/Attean/Store/SPARQL/Role/CreateStore.pm view on Meta::CPAN
}
my $end = RDF::Endpoint->new($model);
my $app = sub {
my $env = shift;
my $req = Plack::Request->new($env);
my $resp = $end->run( $req );
return $resp->finalize;
};
my $useragent = Test::LWP::UserAgent->new;
$useragent->register_psgi('localhost', $app);
# Now, we should just have had a URL of the endpoint
my $url = 'http://localhost:5000/sparql';
my $store = Attean->get_store('SPARQL')->new(endpoint_url => $url,
ua => $useragent
);
return $store;
}
1;
=pod
=head1 NAME
use Test::Modern;
use Attean;
use Attean::RDF;
use AtteanX::Model::SPARQL;
use Data::Dumper;
#use Carp::Always;
my $p = Attean::IDPQueryPlanner->new();
isa_ok($p, 'Attean::IDPQueryPlanner');
my $store = Attean->get_store('SPARQL')->new('endpoint_url' => iri('http://test.invalid/'));
isa_ok($store, 'AtteanX::Store::SPARQL');
does_ok($store, 'Attean::API::TripleStore');
my $model = AtteanX::Model::SPARQL->new( store => $store );
isa_ok($model, 'AtteanX::Model::SPARQL');
does_ok($model, 'Attean::API::CostPlanner');
can_ok($model, 'get_sparql');
my $graph = iri('http://example.org');
my $t = triplepattern(variable('s'), iri('p'), literal('1'));
( run in 1.043 second using v1.01-cache-2.11-cpan-49f99fa48dc )