Attean

 view release on metacpan or  search on metacpan

lib/Attean/SimpleQueryEvaluator.pm  view on Meta::CPAN


  use v5.14;
  use Attean;
  my $algebra = Attean->get_parser('SPARQL')->parse('SELECT * WHERE { ... }');
  my $active_graph = Attean::IRI->new('http://example.org/');
  my $e = Attean::SimpleQueryEvaluator->new( model => $model );
  my $iter = $e->evaluate( $algebra, $active_graph );

=head1 DESCRIPTION

The Attean::SimpleQueryEvaluator class implements a simple query evaluator that,
given an L<Attean::API::Algebra|Attean::API::Query> and a L<Attean::API::Model>
object, evaluates the query represented by the algebra using data from the
model, and returns a query result.

=head1 ATTRIBUTES

=over 4

=cut

use Attean::Algebra;
use Attean::Expression;

package Attean::SimpleQueryEvaluator 0.035 {
	use Moo;
	use Encode qw(encode);
	use Attean::RDF;
	use AtteanX::Functions::CompositeLists;
	use AtteanX::Functions::CompositeMaps;
	use LWP::UserAgent;
	use Scalar::Util qw(blessed);
	use List::Util qw(all any reduce);
	use Types::Standard qw(ConsumerOf InstanceOf Bool Object);
	use URI::Escape;
	use Attean::SPARQLClient;
	use namespace::clean;

=item C<< model >>

The L<Attean::API::Model> object used for query evaluation.

=cut

	has 'model' => (is => 'ro', isa => ConsumerOf['Attean::API::Model'], required => 1);
	
=item C<< default_graph >>

The L<Attean::API::IRI> object representing the default graph in the C<< model >>.
The default graph will be excluded from enumeration of graph names for query
features such as C<< GRAPH ?g {} >>.

=cut

	has 'default_graph'	=> (is => 'ro', isa => ConsumerOf['Attean::API::IRI'], required => 1);

	has 'user_agent' => (is => 'rw', isa => InstanceOf['LWP::UserAgent'], default => sub { my $ua = LWP::UserAgent->new(); $ua->agent("Attean/$Attean::VERSION " . $ua->_agent); $ua });
	
=item C<< request_signer >>

If set, used to modify HTTP::Request objects used in evaluating SERVICE calls
before the request is made. This may be used to, for example, add cryptographic
signature headers to the request. The modification is performed by calling
C<< $request_signer->sign( $request ) >>.

=cut

	has 'request_signer' => (is => 'rw', isa => Object);
	
	has 'ground_blanks' => (is => 'rw', isa => Bool, default => 0);
	
	sub BUILD {
		# Ensure that the CT extensions are registered
		AtteanX::Functions::CompositeLists->register();
		AtteanX::Functions::CompositeMaps->register();
	}
	
=back

=head1 METHODS

=over 4

=item C<< evaluate( $algebra, $active_graph ) >>

Returns an L<Attean::API::Iterator> object with results produced by evaluating
the query C<< $algebra >> against the evaluator's C<< model >>, using the
supplied C<< $active_graph >>.

=cut

	sub evaluate {
		my $self			= shift;
		my $algebra			= shift;
		my $active_graph	= shift || Carp::confess "No active-graph passed to Attean::SimpleQueryEvaluator->evaluate";
		
		Carp::confess "No algebra passed for evaluation" unless ($algebra);
		
		my $expr_eval	= Attean::SimpleQueryEvaluator::ExpressionEvaluator->new( evaluator => $self );

		my @children	= @{ $algebra->children };
		my ($child)		= $children[0];
		if ($algebra->isa('Attean::Algebra::Query') or $algebra->isa('Attean::Algebra::Update')) {
			return $self->evaluate($algebra->child, $active_graph, @_);
		} elsif ($algebra->isa('Attean::Algebra::BGP')) {
			my @triples	= @{ $algebra->triples };
			if (scalar(@triples) == 0) {
				my $b	= Attean::Result->new( bindings => {} );
				return Attean::ListIterator->new(variables => [], values => [$b], item_type => 'Attean::API::Result');
			} else {
				my @iters;
				my @new_vars;
				my %blanks;
				foreach my $t (@triples) {
					push(@iters, $self->evaluate_pattern($t, $active_graph, \@new_vars, \%blanks));
				}
				while (scalar(@iters) > 1) {
					my ($lhs, $rhs)	= splice(@iters, 0, 2);
					unshift(@iters, $lhs->join($rhs));
				}
				return shift(@iters)->map(sub { shift->project_complement(@new_vars) });



( run in 0.602 second using v1.01-cache-2.11-cpan-39bf76dae61 )