RDF::Query::Algebra::Update - Algebra class for UPDATE operations


RDF-Query documentation Contained in the RDF-Query distribution.

Index


Code Index:

NAME

Top

RDF::Query::Algebra::Update - Algebra class for UPDATE operations

VERSION

Top

This document describes RDF::Query::Algebra::Update version 2.907.

METHODS

Top

Beyond the methods documented below, this class inherits methods from the RDF::Query::Algebra class.

new ( $delete_template, $insert_template, $pattern [, \%dataset] )

Returns a new UPDATE structure.

construct_args

Returns a list of arguments that, passed to this class' constructor, will produce a clone of this algebra pattern.

sse

Returns the SSE string for this algebra expression.

as_sparql

Returns the SPARQL string for this algebra expression.

referenced_blanks

Returns a list of the blank node names used in this algebra expression.

referenced_variables
delete_template
insert_template
pattern
dataset

AUTHOR

Top

 Gregory Todd Williams <gwilliams@cpan.org>


RDF-Query documentation Contained in the RDF-Query distribution.
# RDF::Query::Algebra::Update
# -----------------------------------------------------------------------------

package RDF::Query::Algebra::Update;

use strict;
use warnings;
no warnings 'redefine';
use base qw(RDF::Query::Algebra);

use Data::Dumper;
use Log::Log4perl;
use Scalar::Util qw(refaddr);
use Carp qw(carp croak confess);
use Scalar::Util qw(blessed reftype refaddr);
use Time::HiRes qw(gettimeofday tv_interval);
use RDF::Trine::Iterator qw(smap sgrep swatch);

######################################################################

our ($VERSION);
my %TRIPLE_LABELS;
my @node_methods	= qw(subject predicate object);
BEGIN {
	$VERSION	= '2.907';
}

######################################################################

sub new {
	my $class	= shift;
	my $delete	= shift;
	my $insert	= shift;
	my $pat		= shift;
	my $dataset	= shift;
	return bless([$delete, $insert, $pat, $dataset], $class);
}

sub construct_args {
	my $self	= shift;
	return ($self->delete_template, $self->insert_template, $self->pattern);
}

sub sse {
	my $self	= shift;
	my $context	= shift;
	my $indent	= shift;
	
	my $string;
	my $delete	= $self->delete_template;
	my $insert	= $self->insert_template;
	my $dataset	= $self->dataset;
	my @ds_keys	= keys %{ $dataset || {} };
	if (@ds_keys) {
		my @defaults	= sort map { $_->sse } @{ $dataset->{default} || [] };
		my @named		= sort map { $_->sse } values %{ $dataset->{named} || {} };
		my @strings;
		push(@strings, (@defaults) ? '(defaults ' . join(' ', @defaults) . ')' : ());
		push(@strings, (@named) ? '(named ' . join(' ', @named) . ')' : ());
		
		my $ds_string	= '(dataset ' . join(' ', @strings) . ')';
		return sprintf(
			"(update (delete %s) (insert %s) (where %s) %s)",
			($delete ? $delete->sse( $context, $indent ) : ''),
			($insert ? $insert->sse( $context, $indent ) : ''),
			$self->pattern->sse( $context, $indent ),
			$ds_string,
		);
	} else {
		return sprintf(
			"(update (delete %s) (insert %s) (where %s))",
			($delete ? $delete->sse( $context, $indent ) : ''),
			($insert ? $insert->sse( $context, $indent ) : ''),
			$self->pattern->sse( $context, $indent ),
		);
	}
}

sub as_sparql {
	my $self	= shift;
	my $context	= shift || {};
	my $indent	= shift || '';
	my $delete	= $self->delete_template;
	my $insert	= $self->insert_template;
	my $ggp		= $self->pattern;
	
	my $dataset	= $self->dataset;
	my @ds_keys	= keys %{ $dataset || {} };
	my $ds_string	= '';
	if (@ds_keys) {
		my @defaults	= @{ $dataset->{default} || [] };
		my %named		= %{ $dataset->{named} || {} };
		my @strings;
		push(@strings, sprintf("USING <%s>", $_->uri_value)) foreach (@defaults);
		push(@strings, sprintf("USING NAMED <%s>", $named{$_}->uri_value)) foreach (keys %named);
		$ds_string	= join("\n${indent}", @strings);
	}
	
	if ($insert or $delete) {
		# TODO: $(delete|insert)->as_sparql here isn't properly serializing GRAPH blocks, because even though they contain Quad objects inside of BGPs, there's no containing NamedGraph object...
		if ($ds_string) {
			$ds_string	= "\n${indent}$ds_string";
		}
		
		if ($insert and $delete) {
			return sprintf(
				"DELETE {\n${indent}	%s\n${indent}}\n${indent}INSERT {\n${indent}	%s\n${indent}}\n${indent}%s\n${indent}WHERE %s",
				$delete->as_sparql( $context, "${indent}  " ),
				$insert->as_sparql( $context, "${indent}  " ),
				$ds_string,
				$ggp->as_sparql( { %$context, force_ggp_braces => 1 }, ${indent} ),
			);
		} elsif ($insert) {
			return sprintf(
				"INSERT {\n${indent}	%s\n${indent}}\n${indent}%s\n${indent}WHERE %s",
				$insert->as_sparql( $context, "${indent}  " ),
				$ds_string,
				$ggp->as_sparql( { %$context, force_ggp_braces => 1 }, ${indent} ),
			);
		} else {
			return sprintf(
				"DELETE {\n${indent}	%s\n${indent}}\n${indent}%s\n${indent}WHERE %s",
				$delete->as_sparql( $context, "${indent}  " ),
				$ds_string,
				$ggp->as_sparql( { %$context, force_ggp_braces => 1 }, ${indent} ),
			);
		}
	} else {
		my @pats	= $ggp->patterns;
		my $op		= ($delete) ? 'DELETE' : 'INSERT';
		my $temp	= ($delete) ? $delete : $insert;
		my $temps	= ($temp->isa('RDF::Query::Algebra::GroupGraphPattern'))
					? $temp->as_sparql( $context, "${indent}	" )
					: "{\n${indent}	" . $temp->as_sparql( $context, "${indent}	" ) . "\n${indent}}";
		if (scalar(@pats) == 0) {
			return sprintf(
				"${op} DATA %s",
				$temps
			);
		} else {
			if ($ds_string) {
				$ds_string	= "\n${indent}$ds_string\n${indent}";
			} else {
				$ds_string	= ' ';
			}
			return sprintf(
				"${op} %s%sWHERE %s",
				$temps,
				$ds_string,
				$ggp->as_sparql( { %$context, force_ggp_braces => 1 }, "${indent}" ),
			);
		}
	}
}

sub referenced_blanks {
	my $self	= shift;
	return;
}

sub referenced_variables {
	my $self	= shift;
	return;
}

sub delete_template {
	my $self	= shift;
	return $self->[0];
}

sub insert_template {
	my $self	= shift;
	return $self->[1];
}

sub pattern {
	my $self	= shift;
	return $self->[2];
}

sub dataset {
	my $self	= shift;
	return $self->[3];
}


1;

__END__