- From: Dan Brickley <danbri@w3.org>
- Date: Sun, 31 Mar 2002 21:17:52 -0500 (EST)
- To: <www-archive@w3.org>
---------- Forwarded message ----------
Date: Sun, 31 Mar 2002 21:14:02 -0500
From: Dan Brickley <danbri@w3.org>
To: danbri@w3.org
#!/usr/bin/perl
#
##
## a Squish/Algae RDF query convertor
##
## also shows how to use Perllib RDF query API
## optionally converting from Squish format first
##
## bugs: - not fully packaged as a Perl module
## - doesn't use Squish WHERE clause to set datasource
##
## usage: see ./sqtest.pl --data=../../samples/data.rdf
##
## by danbri@w3.org (algae bit based on code from eric@w3.org)
## may 2001
##
## todo: fix syntax / rules for USING clause
## currently we risk screwing up if namespace is abbreviated with
## names like 'for', 'as', 'and'. This is a Squish syntax issue really.
BEGIN {unshift@INC,('../../..','../..');}
use strict;
package RDF::RDFWeb::SquishAlgae;
use W3C::Rdf::RdfApp;
use W3C::Util::Exception;
require Exporter;
use vars qw(@ISA @EXPORT_OK);
@RDF::RDFWeb::SquishAlgae::ISA = qw(W3C::Rdf::RdfApp Exporter);
@EXPORT_OK = qw();
# Constructor method
sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = $class->SUPER::new();
bless $self, $class;
return $self;
}
my $PRINT_TRIPLES=0;
# todo: add a representation of the result set a la Perl DBI
1;
sub doalgae {
my $self= shift;
my $datafile = shift;
my $aquery = shift;
# this stuff replaced by code of erics below
open(OUT,">>/tmp/soap-query") ;
#collect '( ?x ?l ?c )
$aquery =~ m/collect \'\((.*)\)/;
my $vars = $1;
$vars =~ s/\?//g;
my @varnames = split(/\s+/,$vars);
$self->{'varnames'}=\@varnames;
print OUT "DOALGY: vars= $vars\n";
close OUT;
# print "DOALGAE: got data: $datafile query: $aquery\n";
# my $db = $self->{'dbmodname'} || "\"W3C::Rdf::RdfDB\" (\"name:local:/ephemoral\")";
my $db = "\"W3C::Rdf::ObjectDB\" (\"properties:/home/annotest/perl/modules/Conf/rdf.prop\" \"name:http://iggy.w3.org/danbri/\")";
# my $db2 = new W3C::Rdf::ObjectDB(-properties => /home/annotest/perl/modules/Conf/rdf.prop);
# print "doalgy: using dbmodname='$db'\n";
# /home/annotest/perl/modules/Conf/rdf.prop
my @JOB=("-d".$db,$datafile,"-a".$aquery);
## this is how eric's query engine gets called
##
eval {
my $tester = $self;
$tester->execute(\@JOB);
}; if ($@) {if ($@) {if (my $ex = &catch('W3C::Util::Exception')) {
die $ex->toString;
# die $@.' at line '.$tester->{XML_PARSER}->getLineNumber.' column '.$tester->{XML_PARSER}->getColumnNumber;
} else {die $@;}}}
return ( @{ $self->{'resultset'} } );
}
## This is Eric's stuff. I don't know this API well.
##
sub render {
my ($self) = @_;
my @vn = @{$self->{'varnames'}};
#open(OUT,">>/tmp/query");
#print OUT "vars...", join (' ; ',@vn),"\n";
#close OUT;
#todo: the arrayref '$selects' below contains out vars too
my $attrib = $self->{RDF_PARSER}->getRootAttribution;
my $sysID = $self->{RDF_PARSER}->getSystemId;
if ($attrib && $PRINT_TRIPLES) {
print join ("\n", $self->{RDF_DB}->expandStatements(undef, ':', $self->{NAMESPACE_HANDLER},
{-attributions => [$attrib],
-sourceOnly => $self->{ARGS}{-sourceOnly}}));
}
my $queryHandler = $self->{RDF_DB}->getAlgaeInterface;
$queryHandler->setParserEnv($self);
foreach my $query (@{$self->{ARGS}{-algae}}) {
my ($nodes2, $selects, $messages) = $queryHandler->algae($query, $sysID, {-uniqueResults => 1});
# print join ("\n", @$messages)."\n";
# print 'algae "'.$query."\" -> \n".join ("\n", map {'('.join (' ', map {scalar $_->show} @$_).')'} @$nodes2)."\n";
# print 'Algae query: '.$query , "\n";
my $rows=$nodes2;
my @resultset;
my $count=0;
my $ret;
open(LOG_RET, ">>/tmp/log_ret");
# foreach my $row (@$rows) {
my $iRows = @$rows;
print LOG_RET "$iRows rows\n";
foreach (my $iRow = 0; $iRow < $iRows; $iRow++) {
my $row = $rows->[$iRow];
my $proofs = $rows->[$iRow];
my %record;
for (my $colNo = 0; $colNo < @$row; $colNo++) {
$ret='';
my $varName = $selects->[$colNo];
my $column = $row->[$colNo];
$ret .= ' ' if ($colNo > 0);
if ($column->isa('W3C::Rdf::Uri')) {
$ret .= $column->getUri ;
} elsif ($column->isa('W3C::Rdf::String')) {
$ret .= '"'.$column->getString.'"';
} elsif ($column->isa('W3C::Rdf::GenId')) {
$ret .= '"'.$column->getId.'"';
} else {
&throw(new W3C::Util::Exception(-message => "don't know how to serialize \"$column\""));
}
chomp $colNo;
$colNo =~ s/\s+//;
# $record{ $vn[ $colNo ] } = $ret;
$record{ $varName } = $ret;
print LOG_RET "$ret\n\n";
}# cols
push @resultset, \%record;
}# rows
$self->{'resultset'}=\@resultset; # store other stuff too?
}
}
sub formatResultSet {
my $self = shift;
my @rs = @_;
my $ret;
foreach my $rr ( @rs ) {
my %record = %{ $rr };
foreach my $col (sort keys %record) {
$ret .= "$col: $record{$col} \t";
}
$ret .= "\n";
}
return $ret;
}
# filter to turn ilrt squish into ericp algae
sub squish2algae {
my $self=shift;
my $squish = shift;
chomp $squish;
$squish =~ s/\n/ /g;
$squish =~ s/\r/ /g;
$squish =~ m/SELECT\s+(.*)\s*WHERE\s*(.*)\s*USING\s*(.*)/i;
my $SELECT = $1;
my $WHERE = $2;
my $USING = $3;
my $FROM;
if ($SELECT =~ s/FROM\s+(.*)//i) {
$FROM=$1;
}
$SELECT =~ s/SELECT//i;
$FROM =~ s/FROM//i;
$WHERE =~ s/WHERE//i;
$USING =~ s/USING//i;
my @selects = split (/\s+/, $SELECT);
my @froms = split (/\s+/, $FROM);
my $dbg = "Select: \t$SELECT \n\tFrom: $FROM\n\tWhere: $WHERE\n\tUsing: $USING \n";
my %ns;
my @spaces = split(/\s*AND\s*/i, $USING);
if (! @spaces) { push (@spaces, $USING) };
my $pairs = $USING; # note: squish syntax underspecified! :(
$pairs =~ s/for//ig;
$pairs =~ s/as//ig;
$pairs =~ s/and//ig; # sugar; see #todo at top of file
my @nslist = split(/\s+/,$pairs);
while (@nslist) {
my ($x,$y) = (shift @nslist, shift @nslist);
chomp $y;
$ns{$x} = $y;
}
$WHERE =~ s/(\w+)::/$ns{$1}/ig;
$WHERE =~ s/\)\s*\(/)\n\t(/g;
$SELECT =~ s/,//g; # desugar: no commas in var names
my $algae;
$algae .= "(ask '(\n";
$algae .= "$WHERE\n";
$algae .= ") collect '( $SELECT )\n )\n";
return $algae;
}
Received on Sunday, 31 March 2002 21:17:51 UTC