Attean

 view release on metacpan or  search on metacpan

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

		return 0 if ($self->operator =~ m/^(?:RAND|BNODE|UUID|STRUUID|NOW)$/);
		foreach my $c (@{ $self->children }) {
			return 0 unless ($c->is_stable);
		}
		return 1;
	}
	
	sub sparql_tokens {
		my $self	= shift;
		my $func	= AtteanX::SPARQL::Token->keyword($self->operator);
		my $lparen	= AtteanX::SPARQL::Token->lparen;
		my $rparen	= AtteanX::SPARQL::Token->rparen;
		my $comma	= AtteanX::SPARQL::Token->comma;

		my @tokens;
		my @children	= @{ $self->children };
		if ($self->operator eq 'INVOKE') {
			my $iri	= shift(@children);
			push(@tokens, $iri->sparql_tokens->elements);
			push(@tokens, $lparen);
		} else {
			push(@tokens, $func, $lparen);
		}
		
		foreach my $t (@children) {
			push(@tokens, $t->sparql_tokens->elements);
			push(@tokens, $comma);
		}
		if (scalar(@tokens) > 2) {
			pop(@tokens);	# remove the last comma
		}
		push(@tokens, $rparen);
		return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
	}
}

package Attean::AggregateExpression 0.038 {
	use Moo;
	use Types::Standard qw(Bool Enum Str HashRef ConsumerOf Maybe ArrayRef);
	use Types::Common::String qw(UpperCaseStr);
	use AtteanX::SPARQL::Constants;
	use AtteanX::SPARQL::Token;
	use namespace::clean;

	around 'BUILDARGS' => sub {
		my $orig	= shift;
		my $class	= shift;
		my $args	= $class->$orig(@_);
		$args->{operator}	= UpperCaseStr->coercion->($args->{operator});
		return $args;
	};
	sub BUILD {
		my ($self, $args) = @_;

		state $type	= Enum[qw(COUNT SUM MIN MAX AVG GROUP_CONCAT SAMPLE RANK CUSTOM FOLD)];
		$type->assert_valid(shift->operator);
	}
	
	has 'custom_iri'	=> (is => 'ro', isa => Maybe[Str]);
	has 'operator'		=> (is => 'ro', isa => UpperCaseStr, coerce => UpperCaseStr->coercion, required => 1);
	has 'scalar_vars'	=> (is => 'ro', isa => HashRef, default => sub { +{} });
	has 'distinct'		=> (is => 'ro', isa => Bool, default => 0);
	has 'variable'		=> (is => 'ro', isa => ConsumerOf['Attean::API::Variable'], required => 1);
	has 'order' 		=> (is => 'ro', isa => ArrayRef, required => 1, default => sub { [] });

	with 'Attean::API::AggregateExpression';
	with 'Attean::API::SPARQLSerializable';

	sub tree_attributes { return qw(operator scalar_vars variable) }

	sub is_stable {
		my $self	= shift;
		foreach my $expr (@{ $self->groups }, values %{ $self->aggregates }) {
			return 0 unless ($expr->is_stable);
		}
		return 1;
	}

	sub sparql_tokens {
		my $self	= shift;
		my $distinct	= AtteanX::SPARQL::Token->keyword('DISTINCT');
		my $func	= AtteanX::SPARQL::Token->keyword($self->operator);
		my $lparen	= AtteanX::SPARQL::Token->lparen;
		my $rparen	= AtteanX::SPARQL::Token->rparen;
		my $comma	= AtteanX::SPARQL::Token->comma;

		my @tokens;
		push(@tokens, $func);
		push(@tokens, $lparen);
		if ($self->distinct) {
			push(@tokens, $distinct);
		}
		foreach my $t (@{ $self->children }) {
			push(@tokens, $t->sparql_tokens->elements);
			push(@tokens, $comma);
		}
		if (scalar(@tokens) > 2) {
			pop(@tokens);	# remove the last comma
		}
		my $vars	= $self->scalar_vars;
		my @keys	= keys %$vars;
		if (scalar(@keys)) {
			die "TODO: Implement SPARQL serialization for aggregate scalar vars";
		}
		push(@tokens, $rparen);
		return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
	}
}

package Attean::CastExpression 0.038 {
	use Moo;
	use Types::Standard qw(Enum ConsumerOf);
	use AtteanX::SPARQL::Constants;
	use AtteanX::SPARQL::Token;
	use namespace::clean;

	with 'Attean::API::SPARQLSerializable';
	with 'Attean::API::UnaryExpression', 'Attean::API::Expression', 'Attean::API::UnaryQueryTree';

	has 'datatype'	=> (is => 'ro', isa => ConsumerOf['Attean::API::IRI']);
	sub BUILDARGS {
		my $class	= shift;
		return $class->SUPER::BUILDARGS(@_, operator => '_cast');
	}



( run in 0.856 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )