Attean
view release on metacpan or search on metacpan
lib/Attean/Algebra.pm view on Meta::CPAN
use v5.14;
use warnings;
use utf8;
=head1 NAME
Attean::Algebra - Representation of SPARQL algebra operators
=head1 VERSION
This document describes Attean::Algebra version 0.038
=head1 SYNOPSIS
use v5.14;
use Attean;
=head1 DESCRIPTION
This is a utility package that defines all the Attean query algebra classes
in the Attean::Algebra namespace:
=over 4
=cut
use Attean::API::Query;
package Attean::Algebra::Query 0.038 {
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(Bool ArrayRef HashRef ConsumerOf);
use Moo;
use namespace::clean;
has 'dataset' => (is => 'ro', isa => HashRef[ArrayRef[ConsumerOf['Attean::API::Term']]], default => sub { +{} });
has 'subquery' => (is => 'ro', isa => Bool, default => 0);
with 'Attean::API::UnionScopeVariables', 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
sub algebra_as_string {
my $self = shift;
my $name = $self->subquery ? 'SubQuery' : 'Query';
my %dataset = %{ $self->dataset };
my @default = @{ $dataset{ default } || [] };
my @named = @{ $dataset{ named } || [] };
my $has_dataset = (scalar(@default) + scalar(@named));
my $s = $name;
if ($has_dataset) {
my @parts;
if (scalar(@default)) {
push(@parts, 'Default graph(s): ' . join(', ', map { chomp; $_ } map { $_->as_sparql } @default));
}
if (scalar(@named)) {
push(@parts, 'Named graph(s): ' . join(', ', map { chomp; $_ } map { $_->as_sparql } @named));
}
$s .= ' { ' . join('; ', @parts) . ' }';
}
return $s;
}
sub sparql_tokens {
my $self = shift;
my $child = $self->child;
my $l = AtteanX::SPARQL::Token->lbrace;
my $r = AtteanX::SPARQL::Token->rbrace;
my $from = AtteanX::SPARQL::Token->keyword('FROM');
my $named = AtteanX::SPARQL::Token->keyword('NAMED');
my %dataset = %{ $self->dataset };
my @default = @{ $dataset{ default } || [] };
my @named = @{ $dataset{ named } || [] };
my $has_dataset = (scalar(@default) + scalar(@named));
if ($child->does('Attean::API::SPARQLQuerySerializable')) {
if ($self->subquery) {
my @tokens;
push(@tokens, $l);
push(@tokens, $child->sparql_tokens->elements);
push(@tokens, $r);
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
} else {
my %args;
if ($has_dataset) {
$args{dataset} = $self->dataset;
}
return $child->query_tokens(%args);
}
} else {
my $sel = AtteanX::SPARQL::Token->keyword('SELECT');
my $star = AtteanX::SPARQL::Token->star;
my $where = AtteanX::SPARQL::Token->keyword('WHERE');
my @tokens;
if ($self->subquery) {
lib/Attean/Algebra.pm view on Meta::CPAN
use Types::Standard qw(ConsumerOf);
use namespace::clean;
sub in_scope_variables {
my $self = shift;
my ($child) = @{ $self->children };
my @vars = $child->in_scope_variables;
return Set::Scalar->new(@vars, $self->variable->value)->elements;
}
with 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'variable' => (is => 'ro', isa => ConsumerOf['Attean::API::Variable'], required => 1);
has 'expression' => (is => 'ro', isa => ConsumerOf['Attean::API::Expression'], required => 1);
sub algebra_as_string {
my $self = shift;
return sprintf('Extend { %s â %s }', $self->variable->as_string, $self->expression->as_string);
}
sub tree_attributes { return qw(variable expression) };
sub sparql_tokens {
my $self = shift;
my $bind = AtteanX::SPARQL::Token->keyword('BIND');
my $as = AtteanX::SPARQL::Token->keyword('AS');
my $l = AtteanX::SPARQL::Token->lparen;
my $r = AtteanX::SPARQL::Token->rparen;
my ($child) = @{ $self->children };
my $var = $self->variable;
my $expr = $self->expression;
my @tokens;
push(@tokens, $child->sparql_tokens->elements);
push(@tokens, $bind);
push(@tokens, $l);
push(@tokens, $expr->sparql_tokens->elements);
push(@tokens, $as);
push(@tokens, $var->sparql_tokens->elements);
push(@tokens, $r);
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Unfold>
=cut
package Attean::Algebra::Unfold 0.031 {
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Moo;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
sub in_scope_variables {
my $self = shift;
my ($child) = @{ $self->children };
my @vars = $child->in_scope_variables;
return Set::Scalar->new(@vars, map { $_->value } @{ $self->variables })->elements;
}
with 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'variables' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::Variable']], required => 1);
has 'expression' => (is => 'ro', isa => ConsumerOf['Attean::API::Expression'], required => 1);
sub algebra_as_string {
my $self = shift;
my @vars = map { $_->as_string } @{ $self->variables };
my $vars = '(' . join(', ', @vars) . ')';
return sprintf('Unfold { %s â %s }', $vars, $self->expression->as_string);
}
sub tree_attributes { return qw(variables expression) };
sub sparql_tokens {
my $self = shift;
my $explode = AtteanX::SPARQL::Token->keyword('UNFOLD');
my $as = AtteanX::SPARQL::Token->keyword('AS');
my $l = AtteanX::SPARQL::Token->lparen;
my $r = AtteanX::SPARQL::Token->rparen;
my ($child) = @{ $self->children };
my @vars = @{ $self->variables };
my $expr = $self->expression;
my @tokens;
push(@tokens, $child->sparql_tokens->elements);
push(@tokens, $explode);
push(@tokens, $l);
push(@tokens, $expr->sparql_tokens->elements);
push(@tokens, $as);
foreach my $i (0 .. $#vars) {
my $var = $vars[$i];
if ($i > 0) {
push(@tokens, AtteanX::SPARQL::Token->comma);
}
push(@tokens, $var->sparql_tokens->elements);
}
push(@tokens, $r);
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Minus>
=cut
package Attean::Algebra::Minus 0.038 {
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Moo;
use Types::Standard qw(ConsumerOf);
use namespace::clean;
with 'Attean::API::Algebra', 'Attean::API::BinaryQueryTree';
sub in_scope_variables {
my $self = shift;
my ($child) = @{ $self->children };
return $child->in_scope_variables;
}
sub algebra_as_string { return 'Minus' }
sub sparql_tokens {
my $self = shift;
my $minus = AtteanX::SPARQL::Token->keyword('MINUS');
lib/Attean/Algebra.pm view on Meta::CPAN
package Attean::Algebra::Distinct 0.038 {
use Moo;
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::UnionScopeVariables', 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
sub algebra_as_string { return 'Distinct' }
}
=item * L<Attean::Algebra::Reduced>
=cut
package Attean::Algebra::Reduced 0.038 {
use Moo;
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::UnionScopeVariables', 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
sub algebra_as_string { return 'Reduced' }
}
=item * L<Attean::Algebra::Slice>
=cut
package Attean::Algebra::Slice 0.038 {
use Moo;
use Types::Standard qw(Int);
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::UnionScopeVariables', 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'limit' => (is => 'ro', isa => Int, default => -1);
has 'offset' => (is => 'ro', isa => Int, default => 0);
sub algebra_as_string {
my $self = shift;
my @str = ('Slice');
push(@str, "Limit=" . $self->limit) if ($self->limit >= 0);
push(@str, "Offset=" . $self->offset) if ($self->offset > 0);
return join(' ', @str);
}
}
=item * L<Attean::Algebra::Project>
=cut
package Attean::Algebra::Project 0.038 {
use Types::Standard qw(ArrayRef ConsumerOf);
use Moo;
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'variables' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::Variable']], required => 1);
sub in_scope_variables {
my $self = shift;
my ($child) = @{ $self->children };
my $set = Set::Scalar->new( $child->in_scope_variables );
my $proj = Set::Scalar->new( map { $_->value } @{ $self->variables } );
return $set->intersection($proj)->elements;
}
sub algebra_as_string {
my $self = shift;
return sprintf('Project { %s }', join(' ', map { '?' . $_->value } @{ $self->variables }));
}
sub tree_attributes { return qw(variables) };
}
=item * L<Attean::Algebra::Comparator>
=cut
package Attean::Algebra::Comparator 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(Bool ConsumerOf);
use namespace::clean;
has 'ascending' => (is => 'ro', isa => Bool, default => 1);
has 'expression' => (is => 'ro', isa => ConsumerOf['Attean::API::Expression'], required => 1);
sub tree_attributes { return qw(expression) };
sub as_string {
my $self = shift;
if ($self->ascending) {
return 'ASC(' . $self->expression->as_string . ')';
} else {
return 'DESC(' . $self->expression->as_string . ')';
}
}
sub sparql_tokens {
my $self = shift;
my $asc = AtteanX::SPARQL::Token->keyword('ASC');
my $desc = AtteanX::SPARQL::Token->keyword('DESC');
my $l = AtteanX::SPARQL::Token->lparen;
my $r = AtteanX::SPARQL::Token->rparen;
my @tokens;
if ($self->ascending) {
push(@tokens, $self->expression->sparql_tokens->elements);
} else {
push(@tokens, $desc, $l);
push(@tokens, $self->expression->sparql_tokens->elements);
push(@tokens, $r);
}
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::OrderBy>
=cut
package Attean::Algebra::OrderBy 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef InstanceOf);
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::UnionScopeVariables', 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'comparators' => (is => 'ro', isa => ArrayRef[InstanceOf['Attean::Algebra::Comparator']], required => 1);
sub tree_attributes { return qw(comparators) };
sub algebra_as_string {
my $self = shift;
return sprintf('Order { %s }', join(', ', map { $_->as_string } @{ $self->comparators }));
}
}
=item * L<Attean::Algebra::BGP>
=cut
package Attean::Algebra::BGP 0.038 {
use Moo;
use Attean::RDF;
use Set::Scalar;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::Algebra', 'Attean::API::NullaryQueryTree', 'Attean::API::CanonicalizingBindingSet';
has 'triples' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::TriplePattern']], default => sub { [] });
sub in_scope_variables {
my $self = shift;
my $set = Set::Scalar->new();
foreach my $t (@{ $self->triples }) {
my @vars = $t->referenced_variables();
$set->insert(@vars);
}
return $set->elements;
}
sub sparql_tokens {
my $self = shift;
my @tokens;
my $dot = AtteanX::SPARQL::Token->dot;
foreach my $t (@{ $self->triples }) {
push(@tokens, $t->sparql_tokens->elements);
push(@tokens, $dot);
}
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
sub algebra_as_string {
my $self = shift;
return 'BGP { ' . join(', ', map { $_->as_string } @{ $self->triples }) . ' }';
}
sub elements {
my $self = shift;
return @{ $self->triples };
}
sub canonicalize {
my $self = shift;
my ($algebra, $mapping) = $self->canonical_bgp_with_mapping();
my @proj = sort map { sprintf("(?v%03d AS $_)", $mapping->{$_}{id}) } grep { $mapping->{$_}{type} eq 'variable' } (keys %$mapping);
foreach my $var (keys %$mapping) {
$algebra = Attean::Algebra::Extend->new(
children => [$algebra],
variable => variable($var),
expression => Attean::ValueExpression->new( value => variable($mapping->{$var}{id}) ),
);
}
}
sub canonical_bgp_with_mapping {
my $self = shift;
my ($triples, $mapping) = $self->canonical_set_with_mapping();
my $algebra = Attean::Algebra::BGP->new( triples => $triples );
return ($algebra, $mapping);
}
sub tree_attributes { return qw(triples) };
}
=item * L<Attean::Algebra::Service>
=cut
package Attean::Algebra::Service 0.038 {
use AtteanX::SPARQL::Constants;
lib/Attean/Algebra.pm view on Meta::CPAN
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Path>
=cut
package Attean::Algebra::Path 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::Algebra', 'Attean::API::NullaryQueryTree';
has 'subject' => (is => 'ro', isa => ConsumerOf['Attean::API::TermOrVariableOrTriplePattern'], required => 1);
has 'path' => (is => 'ro', isa => ConsumerOf['Attean::API::PropertyPath'], required => 1);
has 'object' => (is => 'ro', isa => ConsumerOf['Attean::API::TermOrVariableOrTriplePattern'], required => 1);
sub in_scope_variables {
my $self = shift;
my @vars = map { $_->value } grep { $_->does('Attean::API::Variable') } ($self->subject, $self->object);
return Set::Scalar->new(@vars)->elements;
}
sub tree_attributes { return qw(subject path object) };
sub algebra_as_string {
my $self = shift;
return 'Path { ' . join(', ', map { $_->as_string } map { $self->$_() } qw(subject path object)) . ' }';
}
sub sparql_tokens {
my $self = shift;
my @tokens;
foreach my $t ($self->subject, $self->path, $self->object) {
push(@tokens, $t->sparql_tokens->elements);
}
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Group>
=cut
package Attean::Algebra::Group 0.038 {
use utf8;
use Moo;
use Attean::API::Query;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'groupby' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::Expression']]);
has 'aggregates' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::AggregateExpression']]);
sub BUILD {
my $self = shift;
foreach my $a (@{ $self->aggregates }) {
my $op = $a->operator;
if ($op eq 'RANK') {
if (scalar(@{ $self->aggregates }) > 1) {
die "Cannot use both aggregates and RANKing in grouping operator";
}
}
}
}
sub in_scope_variables {
my $self = shift;
my $aggs = $self->aggregates // [];
my $groups = $self->groupby // [];
my %vars;
foreach my $a (@$aggs) {
$vars{ $a->variable->value }++;
}
foreach my $e (@$groups) {
if ($e->isa('Attean::ValueExpression')) {
my $value = $e->value;
if ($value->does('Attean::API::Variable')) {
$vars{ $value->value }++;
}
}
}
return keys %vars;
}
sub algebra_as_string {
my $self = shift;
my @aggs;
my $aggs = $self->aggregates // [];
my $groups = $self->groupby // [];
foreach my $a (@$aggs) {
my $v = $a->variable->as_string;
my $op = $a->operator;
my $d = $a->distinct ? "DISTINCT " : '';
my ($e) = ((map { $_->as_string } @{ $a->children }), '');
my $s = "$v â ${op}($d$e)";
push(@aggs, $s);
}
return sprintf('Group { %s } aggregate { %s }', join(', ', map { $_->as_string() } @$groups), join(', ', @aggs));
}
sub tree_attributes { return qw(groupby aggregates) };
}
=item * L<Attean::Algebra::NegatedPropertySet>
=cut
package Attean::Algebra::NegatedPropertySet 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::PropertyPath';
has 'predicates' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::IRI']], required => 0, default => sub { [] });
has 'reversed' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::IRI']], required => 0, default => sub { [] });
sub as_string {
my $self = shift;
my @forward = map { $_->ntriples_string } @{ $self->predicates };
my @rev = map { '^' . $_->ntriples_string } @{ $self->reversed };
return sprintf("!(%s)", join('|', @forward, @rev));
}
sub algebra_as_string { return 'NPS' }
sub tree_attributes { return qw(predicates reversed) };
sub as_sparql {
my $self = shift;
my @forward = map { $_->as_sparql } @{ $self->predicates };
my @rev = map { '^' . $_->as_sparql } @{ $self->reversed };
return sprintf("!(%s)", join('|', @forward, @rev));
}
sub sparql_tokens {
my $self = shift;
my $bang = AtteanX::SPARQL::Token->op_bang;
my $or = AtteanX::SPARQL::Token->path_or;
my $hat = AtteanX::SPARQL::Token->path_hat;
my $l = AtteanX::SPARQL::Token->lparen;
my $r = AtteanX::SPARQL::Token->rparen;
my @tokens;
push(@tokens, $bang, $l);
foreach my $t (@{ $self->predicates }) {
push(@tokens, $t->sparql_tokens->elements);
push(@tokens, $or);
}
foreach my $t (@{ $self->reversed }) {
push(@tokens, $hat);
push(@tokens, $t->sparql_tokens->elements);
push(@tokens, $or);
}
pop(@tokens); # remove last OR token
push(@tokens, $r);
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::PredicatePath>
=cut
package Attean::Algebra::PredicatePath 0.038 {
use Moo;
use Types::Standard qw(ConsumerOf);
use namespace::clean;
with 'Attean::API::PropertyPath';
has 'predicate' => (is => 'ro', isa => ConsumerOf['Attean::API::IRI'], required => 1);
sub as_string {
my $self = shift;
return $self->predicate->ntriples_string;
}
sub algebra_as_string {
my $self = shift;
return 'Property Path ' . $self->as_string;
lib/Attean/Algebra.pm view on Meta::CPAN
push(@tokens, $plus);
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::ZeroOrOnePath>
=cut
package Attean::Algebra::ZeroOrOnePath 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ConsumerOf);
use namespace::clean;
with 'Attean::API::UnaryPropertyPath';
sub postfix_name { return "?" }
sub as_sparql {
my $self = shift;
my ($path) = @{ $self->children };
return $self->path->as_sparql . '?';
}
sub sparql_tokens {
my $self = shift;
my $q = AtteanX::SPARQL::Token->question;
my $l = AtteanX::SPARQL::Token->lparen;
my $r = AtteanX::SPARQL::Token->rparen;
my @tokens;
foreach my $t (@{ $self->children }) {
push(@tokens, $t->sparql_tokens->elements);
}
if (scalar(@tokens) > 1) {
unshift(@tokens, $l);
push(@tokens, $r);
}
push(@tokens, $q);
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Table>
=cut
package Attean::Algebra::Table 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::Algebra', 'Attean::API::NullaryQueryTree';
has variables => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::Variable']]);
has rows => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::Result']]);
sub in_scope_variables {
my $self = shift;
return map { $_->value } @{ $self->variables };
}
sub tree_attributes { return qw(variables rows) };
sub algebra_as_string { return 'Table' }
sub sparql_tokens {
my $self = shift;
my $values = AtteanX::SPARQL::Token->keyword('VALUES');
my $lparen = AtteanX::SPARQL::Token->lparen;
my $rparen = AtteanX::SPARQL::Token->rparen;
my $lbrace = AtteanX::SPARQL::Token->lbrace;
my $rbrace = AtteanX::SPARQL::Token->rbrace;
my @tokens;
push(@tokens, $values);
push(@tokens, $lparen);
foreach my $var (@{ $self->variables }) {
push(@tokens, $var->sparql_tokens->elements);
}
push(@tokens, $rparen);
push(@tokens, $lbrace);
foreach my $row (@{ $self->rows }) {
push(@tokens, $lparen);
foreach my $val ($row->values) {
# TODO: verify correct serialization of UNDEF
push(@tokens, $val->sparql_tokens->elements);
}
push(@tokens, $rparen);
}
push(@tokens, $rbrace);
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Ask>
=cut
package Attean::Algebra::Ask 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
sub in_scope_variables { return; }
sub algebra_as_string { return 'Ask' }
}
=item * L<Attean::Algebra::Construct>
=cut
package Attean::Algebra::Construct 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'triples' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::TriplePattern']]);
sub in_scope_variables { return qw(subject predicate object); }
sub tree_attributes { return; }
sub algebra_as_string {
my $self = shift;
my $triples = $self->triples;
return sprintf('Construct { %s }', join(' . ', map { $_->as_string } @$triples));
}
}
=item * L<Attean::Algebra::Describe>
=cut
package Attean::Algebra::Describe 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::SPARQLQuerySerializable';
with 'Attean::API::Algebra', 'Attean::API::UnaryQueryTree';
has 'terms' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::TermOrVariable']]);
sub in_scope_variables { return qw(subject predicate object); }
sub tree_attributes { return; }
sub algebra_as_string { return 'Describe' }
}
=item * L<Attean::Algebra::Load>
=cut
package Attean::Algebra::Load 0.038 {
use Moo;
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(Bool ConsumerOf);
use namespace::clean;
with 'Attean::API::Algebra', 'Attean::API::NullaryQueryTree';
has 'silent' => (is => 'ro', isa => Bool, default => 0);
has 'url' => (is => 'ro', isa => ConsumerOf['Attean::API::IRI'], required => 1);
has 'graph' => (is => 'ro', isa => ConsumerOf['Attean::API::Term'], predicate => 'has_graph');
sub in_scope_variables { return; }
sub tree_attributes { return; }
sub algebra_as_string {
my $self = shift;
return 'Load ' . $self->url->as_string;
}
sub sparql_tokens {
my $self = shift;
my @tokens;
push(@tokens, AtteanX::SPARQL::Token->keyword('LOAD'));
if ($self->silent) {
push(@tokens, AtteanX::SPARQL::Token->keyword('SILENT'));
}
push(@tokens, $self->url->sparql_tokens->elements);
if ($self->has_graph) {
push(@tokens, AtteanX::SPARQL::Token->keyword('INTO'));
push(@tokens, AtteanX::SPARQL::Token->keyword('GRAPH'));
push(@tokens, $self->graph->sparql_tokens->elements);
}
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Clear>
=cut
package Attean::Algebra::Clear 0.038 {
use Moo;
use Scalar::Util qw(blessed);
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use Types::Standard qw(Enum Bool ConsumerOf);
use namespace::clean;
lib/Attean/Algebra.pm view on Meta::CPAN
has 'silent' => (is => 'ro', isa => Bool, default => 0);
has 'drop_source' => (is => 'ro', isa => Bool, default => 0);
has 'drop_destination' => (is => 'ro', isa => Bool, default => 0);
has 'source' => (is => 'ro', isa => ConsumerOf['Attean::API::Term'], predicate => 'has_source');
has 'destination' => (is => 'ro', isa => ConsumerOf['Attean::API::Term'], predicate => 'has_destination');
sub in_scope_variables { return; }
sub tree_attributes { return; }
sub algebra_as_string {
my $self = shift;
return ($self->drop_source and $self->drop_destination) ? 'Move' : ($self->drop_destination) ? 'Copy' : 'Add';
}
sub sparql_tokens {
my $self = shift;
my @tokens;
my $op = ($self->drop_source and $self->drop_destination) ? 'MOVE' : ($self->drop_destination) ? 'COPY' : 'ADD';
push(@tokens, AtteanX::SPARQL::Token->keyword($op));
if ($self->silent) {
push(@tokens, AtteanX::SPARQL::Token->keyword('SILENT'));
}
if ($self->has_source) {
push(@tokens, AtteanX::SPARQL::Token->keyword('GRAPH'));
push(@tokens, $self->source->sparql_tokens->elements);
} else {
push(@tokens, AtteanX::SPARQL::Token->keyword('DEFAULT'));
}
push(@tokens, AtteanX::SPARQL::Token->keyword('TO'));
if ($self->has_destination) {
push(@tokens, AtteanX::SPARQL::Token->keyword('GRAPH'));
push(@tokens, $self->destination->sparql_tokens->elements);
} else {
push(@tokens, AtteanX::SPARQL::Token->keyword('DEFAULT'));
}
return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
}
}
=item * L<Attean::Algebra::Modify>
=cut
package Attean::Algebra::Modify 0.038 {
use Moo;
use Scalar::Util qw(blessed);
use AtteanX::SPARQL::Constants;
use AtteanX::SPARQL::Token;
use List::Util qw(all any);
use Types::Standard qw(HashRef ArrayRef ConsumerOf);
use namespace::clean;
with 'Attean::API::Algebra', 'Attean::API::QueryTree';
has 'dataset' => (is => 'ro', isa => HashRef, default => sub { +{} });
has 'insert' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::TripleOrQuadPattern']], default => sub { [] });
has 'delete' => (is => 'ro', isa => ArrayRef[ConsumerOf['Attean::API::TripleOrQuadPattern']], default => sub { [] });
sub in_scope_variables { return; }
sub tree_attributes { return; }
sub _op_type {
my $self = shift;
my $i = scalar(@{ $self->insert });
my $d = scalar(@{ $self->delete });
my $w = scalar(@{ $self->children });
my $ig = all { $_->is_ground } @{ $self->insert };
my $dg = all { $_->is_ground } @{ $self->delete };
if ($i and not $d) {
# INSERT
return ($ig and not $w) ? 'ID' : 'I';
} elsif ($d and not $i) {
# DELETE
return ($dg and not $w) ? 'DD' : 'D';
} else {
# INSERT + DELETE
return 'U'
}
}
around 'blank_nodes' => sub {
my $orig = shift;
my $self = shift;
my @blanks = $orig->($self, @_);
my %seen = map { $_->value => 1 } @blanks;
foreach my $data ($self->insert, $self->delete) {
my @triples = @{ $data };
my @b = grep { $_->does('Attean::API::Blank') } map { $_->values } @triples;
push(@blanks, grep { not $seen{$_->value}++ } @b);
}
return @blanks;
};
sub algebra_as_string {
my $self = shift;
my $level = shift;
my $indent = ' ' x ($level + 1);
state $S = {
'ID' => 'Insert Data',
'I' => 'Insert',
'DD' => 'Delete Data',
'D' => 'Delete',
'U' => 'Update',
};
my $op = $self->_op_type();
my $s = $S->{ $op };
my @data;
my $ic = scalar(@{ $self->insert });
my $dc = scalar(@{ $self->delete });
if ($ic) {
my $name = $dc ? 'Insert Data' : 'Data';
push(@data, [$name, $self->insert]);
}
if ($dc) {
my $name = $ic ? 'Delete Data' : 'Data';
push(@data, [$name, $self->delete]);
}
( run in 0.712 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )