kasei / attean

A Perl Semantic Web Framework
19 stars 10 forks source link

SPARQL helpers/doc/examples #149

Closed VladimirAlexiev closed 4 years ago

VladimirAlexiev commented 4 years ago

I'm just trying to do some SPARQL queries. With Trine I used to do this (with memory store)

my $store = RDF::Trine::Store::Memory->new();
my $model = RDF::Trine::Model->new($store) or die "can't create model: $!\n";
my $parser = RDF::Trine::Parser->new('turtle');
$parser->parse_into_model (undef, $turtle, $model);
my $query = RDF::Query->new($SPARQL);
my $it = $query->execute($model);
while (my $row = $it->next) {

or that (with external repo):

    my $query = RDF::Query::Client->new($SPARQL);
    my $it = $query->execute($URL, {UserAgent => $ua, QueryParameter=>"query", QueryMethod =>"POST", AuthUsername=>USER, AuthPassword=>PASS})
      or die "can't query: ", $query->error(), "\n";
    while (my $row = $it->next) {

I spent 15 minutes on CPAN trying to figure out how to do that with Attean. Finally I found it on github: https://github.com/kasei/attean/blob/master/bin/attean_query. This helps immensely, but it seems a fair bit complicated, maybe double the lines of what's shown above. There's eval{..} etc etc.

So my questions:

kasei commented 4 years ago

Because of some of the fundamental changes between Trine and Attean (e.g. in simplifying the store/model code to always work in terms of quads), there's definitely more code.

I'd be happy to try to implement similar convenience methods to what was available in Trine, though. I think there's probably easy extensions we could make for setting up an in-memory store/model, parsing a string of turtle into a model, and turning algebra+model objects into a results iterator.

kasei commented 4 years ago

@VladimirAlexiev with #150, I think your example expands by only one line compared to Trine:

my $ttl_parser  = Attean->get_parser('Turtle')->new();
my $rq_parser   = Attean->get_parser('SPARQL')->new();

my $graph   = iri('http://example.org/');
my $model   = Attean->temporary_model;
$ttl_parser->parse_bytes_into_model($turtle, $model, $graph);

my ($algebra)   = $rq_parser->parse($sparql);
my $results = $model->evaluate($algebra, $graph);

while (my $r = $results->next) {
    say $r->as_string;
}

If you're happy with that as a first step, I'll add it to the example in the Attean synopsis section.

kasei commented 4 years ago

Perhaps parse_bytes_into_model should really be parse_string_into_model, though? For a convenience method like this, would the expectation be that the RDF data is in a native string, not an encoded set of bytes?

kasei commented 4 years ago

Some of this was already implemented, and I seem to have forgotten! 🤦‍♂️

https://github.com/kasei/attean/blob/4021e92589fd8f68f73b813d23f5e3718c801194/lib/Attean/API/Model.pm#L359

my $graph   = iri('http://example.org/');
my $model   = Attean->temporary_model;
$model->load_triples('turtle', $graph, $data);
VladimirAlexiev commented 4 years ago

@kasei thanks!

About the bytes vs string question, I can't really say. I think turtle and ntriples demand UTF8, so the difference is a bit moot?

I currently use a file not string:

    my $iter    = $parser->parse_iter_from_io($fh);
    my $quads   = $iter->as_quads($graph);
    $model->add_iter($quads);

Do you also have a convenience method parse_io_into_model() ?