~ubuntu-branches/debian/lenny/redland-bindings/lenny

« back to all changes in this revision

Viewing changes to demos/query.pl

  • Committer: Bazaar Package Importer
  • Author(s): Dave Beckett
  • Date: 2007-12-27 22:22:07 UTC
  • mfrom: (0.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20071227222207-hxy4hqsw2oupruq5
Tags: 1.0.7.1-1
* New upstream release
* Add /etc/php5/conf.d/redland.ini file to php5-librdf

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/perl -Tw
2
 
#
3
 
# query.pl - Redland RDF Query demo
4
 
#
5
 
# $Id: query.pl 10586 2006-03-05 07:49:32Z cmdjb $
6
 
#
7
 
# Copyright (C) 2004-2006, David Beckett http://purl.org/net/dajobe/
8
 
# Copyright (C) 2004-2005, University of Bristol, UK http://www.bristol.ac.uk/
9
 
10
 
# This package is Free Software and part of Redland http://librdf.org/
11
 
12
 
# It is licensed under the following three licenses as alternatives:
13
 
#   1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
14
 
#   2. GNU General Public License (GPL) V2 or any newer version
15
 
#   3. Apache License, V2.0 or any newer version
16
 
17
 
# You may not use this file except in compliance with at least one of
18
 
# the above three licenses.
19
 
20
 
# See LICENSE.html or LICENSE.txt at the top of this package for the
21
 
# complete terms and further detail along with the license texts for
22
 
# the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
23
 
24
 
25
 
#
26
 
 
27
 
# CHANGE THIS FOR YOUR CONFIGURATION
28
 
$::ROOT_DIR='/somewhere';
29
 
 
30
 
use strict;
31
 
 
32
 
# Helps with broken web requests (missing headers)
33
 
$ENV{'Content-Length'}||=0;
34
 
 
35
 
# Tainting, dontcha know
36
 
$ENV{'PATH'}="/bin:/usr/bin:/usr/local/bin";
37
 
 
38
 
# Standard perl modules
39
 
use CGI;
40
 
use LWP::Simple;
41
 
use URI::URL;
42
 
 
43
 
# Configuration
44
 
 
45
 
my(@query_languages)=qw(rdql sparql),
46
 
my(%query_language_labels)=('rdql'  =>'RDQL',
47
 
                            'sparql' =>'SPARQL');
48
 
my $default_query_language='sparql';
49
 
 
50
 
my $example_foaf_uri='http://purl.org/net/dajobe/webwho.xrdf';
51
 
my $example_rss_uri='http://www.w3.org/2000/08/w3c-synd/home.rss';
52
 
 
53
 
my(%query_examples)=(
54
 
  'rdql' => [
55
 
{ Q => <<EOT
56
 
select ?name
57
 
where
58
 
  (?x rdf:type foaf:Person)
59
 
  (?x foaf:name ?name)
60
 
using foaf for <http://xmlns.com/foaf/0.1/>
61
 
EOT
62
 
 , D => $example_foaf_uri
63
 
 , T => 'A FOAF query that finds the names of all the people in the graph'
64
 
}  , 
65
 
{ Q => <<EOT
66
 
select ?nick, ?name where 
67
 
  (?x rdf:type foaf:Person) (?x foaf:nick ?nick) (?x foaf:name ?name)
68
 
using foaf for <http://xmlns.com/foaf/0.1/>
69
 
EOT
70
 
 , D => $example_foaf_uri
71
 
 , T => 'A FOAF query that finds all people with a name and an IRC nick'
72
 
},
73
 
{ Q => <<'EEEEE'
74
 
select ?name, ?archives
75
 
where
76
 
  (?list rdf:type doaml:MailingList)
77
 
  (?list doaml:name ?name)
78
 
  (?list doaml:archives ?archives)
79
 
and ?name =~ /p3p/
80
 
using doaml for <http://ns.balbinus.net/doaml#>
81
 
EEEEE
82
 
 , D => 'http://www.doaml.net/doaml/w3ml/Lists.rdf'
83
 
 , T => 'Print the name and archive URIs of W3C mailing lists about P3P as described by <a href="http://www.doaml.net/">DOAML</a>'
84
 
},
85
 
  ],
86
 
 
87
 
  'sparql' => [
88
 
{ Q => <<EOT
89
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
90
 
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
91
 
SELECT DISTINCT ?name
92
 
WHERE {
93
 
  ?x rdf:type foaf:Person .
94
 
  ?x foaf:name ?name
95
 
}
96
 
ORDER BY ?name
97
 
EOT
98
 
 , D => $example_foaf_uri
99
 
 , T => 'A FOAF query that finds the names of all the people in the graph'
100
 
}
101
 
  , 
102
 
{ Q => <<EOT
103
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
104
 
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
105
 
SELECT ?nick, ?name
106
 
WHERE { ?x rdf:type foaf:Person . ?x foaf:nick ?nick . ?x foaf:name ?name }
107
 
EOT
108
 
 , D => $example_foaf_uri
109
 
 , T => 'A FOAF query that finds all people with a name and an IRC nick'
110
 
}
111
 
  , 
112
 
{ Q => <<AAAAA
113
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
114
 
PREFIX dc: <http://purl.org/dc/elements/1.1/>
115
 
PREFIX rss: <http://purl.org/rss/1.0/>
116
 
SELECT ?title ?description
117
 
WHERE { ?item rdf:type rss:item .
118
 
       ?item rss:title ?title .
119
 
       ?item rss:description ?description }
120
 
AAAAA
121
 
 , D => $example_rss_uri
122
 
 , T => 'An RSS 1.0 query that finds all the items in the feed'
123
 
},
124
 
{ Q => <<'CCCCC'
125
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
126
 
PREFIX iemsr: <http://www.ukoln.ac.uk/projects/iemsr/terms/>
127
 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
128
 
 
129
 
SELECT $number $name $description
130
 
WHERE {
131
 
  $r rdf:type iemsr:RootDataElement .
132
 
  $n iemsr:isChildOf $r .
133
 
  $n iemsr:refNumber $number .
134
 
  $n rdfs:label $name .
135
 
  $n rdfs:comment $description
136
 
}
137
 
CCCCC
138
 
 , D => 'http://www.ukoln.ac.uk/projects/iemsr/terms/LOM/'
139
 
 , T => 'Find all LOM root elements in the LOM encoded for the <a href="http://www.ukoln.ac.uk/projects/iemsr/">JISC IE Schema Registry</a> (my current project)'
140
 
},
141
 
{ Q => <<'DDDDD'
142
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
143
 
PREFIX doap: <http://usefulinc.com/ns/doap#>
144
 
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
145
 
 
146
 
SELECT $description $maintainerName
147
 
WHERE {
148
 
  $project rdf:type doap:Project .
149
 
  $project doap:description $description .
150
 
  $project doap:maintainer $m .
151
 
  $m foaf:name $maintainerName
152
 
}
153
 
DDDDD
154
 
 , D => 'http://svn.usefulinc.com/svn/repos/trunk/doap/examples/gnome-bluetooth-doap.rdf'
155
 
 , T => 'Print the description of a project and maintainer(s) using <a href="http://usefulinc.com/doap">DOAP</a>'
156
 
},
157
 
{ Q => <<'EEEEE'
158
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
159
 
PREFIX doaml: <http://ns.balbinus.net/doaml#>
160
 
 
161
 
SELECT ?name ?archives
162
 
WHERE {
163
 
  ?list rdf:type doaml:MailingList .
164
 
  ?list doaml:name ?name .
165
 
  ?list doaml:archives ?archives .
166
 
  FILTER REGEX(?name, "p3p")
167
 
}
168
 
EEEEE
169
 
 , D => 'http://www.doaml.net/doaml/w3ml/Lists.rdf'
170
 
 , T => 'Print the name and archive URIs of W3C mailing lists about P3P as described by <a href="http://www.doaml.net/">DOAML</a>'
171
 
},
172
 
{ Q => <<'optional-example1'
173
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
174
 
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
175
 
SELECT ?name ?nick
176
 
WHERE {
177
 
  ?x rdf:type foaf:Person .
178
 
  ?x foaf:name ?name .
179
 
  OPTIONAL { ?x foaf:nick ?nick }
180
 
}
181
 
optional-example1
182
 
 , D => $example_foaf_uri,
183
 
 , T => 'Print the names and optional nicks of people in my FOAF file where available'
184
 
},
185
 
{ Q => <<'podcasts',
186
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
187
 
PREFIX dc: <http://purl.org/dc/elements/1.1/>
188
 
PREFIX rss: <http://purl.org/rss/1.0/>
189
 
PREFIX enc: <http://purl.oclc.org/net/rss_2.0/enc#>
190
 
SELECT ?title ?enc ?len
191
 
WHERE {
192
 
      ?item rdf:type rss:item .
193
 
      ?item rss:title ?title .
194
 
      ?enclosure rdf:type enc:Enclosure .
195
 
      ?item enc:enclosure ?enclosure .
196
 
      ?enclosure enc:url ?enc .
197
 
      ?enclosure enc:type ?type .
198
 
      ?enclosure enc:length ?len .
199
 
      FILTER regex(?type, "audio/mpeg")
200
 
     }
201
 
podcasts
202
 
,
203
 
, D => 'http://B4mad.Net/datenbrei/feed/rdf',
204
 
, T => 'What podcasts have you got in your RSS feed?  (you will need an RSS feed using the enclosures vocab) ',
205
 
},
206
 
{ Q => <<'PERIODIC',
207
 
PREFIX table: <http://www.daml.org/2003/01/periodictable/PeriodicTable#>
208
 
PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
209
 
SELECT ?name ?symbol ?weight ?number
210
 
WHERE {
211
 
 ?element table:group ?group .
212
 
 ?group table:name "Noble gas"^^xsd:string .
213
 
 ?element table:name ?name .
214
 
 ?element table:symbol ?symbol .
215
 
 ?element table:atomicWeight ?weight .
216
 
 ?element table:atomicNumber ?number
217
 
}
218
 
ORDER BY ASC(?name)
219
 
PERIODIC
220
 
, D => 'http://www.daml.org/2003/01/periodictable/PeriodicTable.owl',
221
 
, T => 'What are the Noble Gases?',
222
 
},
223
 
{ Q => <<'DAWG',
224
 
PREFIX collab: <http://www.w3.org/2000/10/swap/pim/collab@@#>
225
 
SELECT ?desc ?R
226
 
WHERE {
227
 
  ?issue collab:shortDesc ?desc;
228
 
  collab:resolveRecord ?R
229
 
}
230
 
DAWG
231
 
, D => 'http://www.w3.org/2000/06/webdata/xslt?xslfile=http%3A%2F%2Fwww.w3.org%2F2003%2F11%2Frdf-in-xhtml-processor&xmlfile=http%3A%2F%2Fwww.w3.org%2F2001%2Fsw%2FDataAccess%2Fissues',
232
 
, T => 'What are the RDF DAWG issues?',
233
 
},
234
 
{ Q => <<'ATOM',
235
 
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
236
 
PREFIX dc: <http://purl.org/dc/elements/1.1/>
237
 
PREFIX rss: <http://purl.org/rss/1.0/>
238
 
PREFIX atom: <http://www.w3.org/2005/Atom>
239
 
SELECT ?item ?title ?date
240
 
WHERE { ?item rdf:type rss:item .
241
 
        ?item rss:title ?title .
242
 
        ?item atom:updated ?date }
243
 
ORDER BY DESC(?date)
244
 
LIMIT 10
245
 
ATOM
246
 
, D => 'http://www.tbray.org/ongoing/ongoing.atom',
247
 
, T => 'What are the last 10 updated items in an atom feed?',
248
 
},
249
 
{ Q => <<'BRUNEL',
250
 
PREFIX : <http://www.commonobjects.example.org/gmlrss>
251
 
PREFIX bio: <http://purl.org/vocab/bio/0.1/>
252
 
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
253
 
 
254
 
SELECT ?name ?birthDate ?deathDate
255
 
WHERE {
256
 
  ?bridge a :Bridge;
257
 
    foaf:maker ?person [
258
 
      foaf:name ?name;
259
 
      bio:event [
260
 
        a bio:Birth;
261
 
        bio:date ?birthDate
262
 
      ];
263
 
      bio:event [
264
 
        a bio:Death;
265
 
        bio:date ?deathDate
266
 
      ]
267
 
    ]
268
 
}
269
 
BRUNEL
270
 
, D => 'http://www.w3.org/2003/01/geo/rdfgml/tests/mixing-eg1.xml',
271
 
, T => 'Who made a bridge in Bristol and what birth/death dates did they have?',
272
 
},
273
 
{ Q => <<'REDLAND-NEWS',
274
 
PREFIX dc: <http://purl.org/dc/elements/1.1/>
275
 
PREFIX rss: <http://purl.org/rss/1.0/>
276
 
SELECT ?item ?title ?date
277
 
WHERE {
278
 
  ?item a rss:item ;
279
 
        rss:title ?title ;
280
 
        dc:date ?date
281
 
}
282
 
ORDER BY DESC(?date)
283
 
LIMIT 10
284
 
REDLAND-NEWS
285
 
  D => 'http://librdf.org/NEWS.rdf http://librdf.org/raptor/NEWS.rdf http://librdf.org/rasqal/NEWS.rdf http://librdf.org/bindings/NEWS.rdf',
286
 
  T => 'Find the most recent 10 news items about Redland from multiple RSS 1.0 feeds',
287
 
},
288
 
  ]
289
 
);
290
 
 
291
 
my(%query_blurbs)=(
292
 
  'rdql' => <<EOT
293
 
  <p>Documentation on RDQL is available in the <a href="http://www.w3.org/Submission/2004/SUBM-RDQL-20040109/">specification</a> and the <a href="http://www.hpl.hp.com/semweb/doc/tutorial/RDQL/">Jena RDQL tutorial</a></p>
294
 
 
295
 
  <p>See the <a href="http://librdf.org/rasqal/TODO.html#rdql">status of RDQL support in Rasqal</a></p>
296
 
EOT
297
 
  ,
298
 
  'sparql' => <<EOT
299
 
  <p>Documentation on SPARQL is available in the <a href="http://www.w3.org/TR/rdf-sparql-query/">SPARQL Query Language for RDF</a>, W3C Working Draft, 12 October 2004</p>
300
 
 
301
 
  <p><b>NOTE</b> Not all of SPARQL is implemented. See the <a href="http://librdf.org/rasqal/TODO.html#sparql">status of SPARQL support in Rasqal</a>.  Current unimplemented features include <code>UNION</code> and full XSD datatype comparisons (dates, decimal) and promotions, <code>GRAPH</code> and deeply grouped graph patterns <code>{</code>...<code>}</code>.</p>
302
 
EOT
303
 
);
304
 
 
305
 
 
306
 
 
307
 
my $log_file="$::ROOT_DIR/logs/query.log";
308
 
 
309
 
 
310
 
 
311
 
my $max_stream_size=200;
312
 
my $max_result_size=200;
313
 
 
314
 
my(%namespaces)=(
315
 
  'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
316
 
  'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
317
 
  'dc' => 'http://purl.org/dc/elements/1.1/',
318
 
  'owl' => 'http://www.w3.org/2002/07/owl#',
319
 
#  'xsd' => 'http://www.w3.org/2001/XMLSchema#',
320
 
  'foaf' => 'http://xmlns.com/foaf/0.1/',
321
 
  'dcterms' => 'http://purl.org/dc/terms/',
322
 
  'bot' => 'http://www.w3.org/2001/sw/Europe/200401/bot/terms\#',
323
 
);
324
 
 
325
 
 
326
 
# Redland perl modules
327
 
 
328
 
use RDF::Redland;
329
 
 
330
 
#  $RDF::Debug=1;
331
 
 
332
 
 
333
 
######################################################################
334
 
# Subroutines
335
 
 
336
 
sub log_action ($$$;$) {
337
 
  my($host, $db, $message, $now)=@_;
338
 
  $now ||= time;
339
 
  return unless open (LOG, ">>$log_file");
340
 
  my($sec,$min,$hour,$mday,$mon,$year)=gmtime $now;
341
 
  my $date=sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",1900+$year,$mon+1,$mday,$hour,$min,$sec);
342
 
  $message =~ s/[\n\s]+/ /gs
343
 
    if $message;
344
 
  print LOG "$host $date $db $message\n";
345
 
  close(LOG);
346
 
}
347
 
 
348
 
sub end_page($) {
349
 
  my $q=shift;
350
 
 
351
 
  print <<'EOT';
352
 
<p>The source code of this demonstration is available in the Redland
353
 
bindings distribution as <tt>demos/query.pl</tt> or from the
354
 
<a href="http://librdf.org/">Redland</a> website</p>
355
 
EOT
356
 
 
357
 
  print qq{<hr />\n\n<p class="copyright"><a href="http://purl.org/net/dajobe/">Dave Beckett</a></p>\n\n</div></body>\n</html>\n};
358
 
}
359
 
 
360
 
sub html_escape ($) {
361
 
  my $str=shift;
362
 
  $str =~ s/\&/\&amp;/g;
363
 
  $str =~ s/</\&lt;/g;
364
 
  $str =~ s/</\&gt;/g;
365
 
  $str;
366
 
}
367
 
 
368
 
sub format_node($) {
369
 
  my $node=shift;
370
 
  my $node_label;
371
 
 
372
 
  if(!defined $node) {
373
 
    $node_label="&nbsp;";
374
 
  } elsif($node->is_resource) {
375
 
    $node_label=$node->uri->as_string;
376
 
    $node_label=qq{<a href="$node_label">$node_label</a>};
377
 
  } elsif ($node->is_literal) {
378
 
    $node_label=$node->literal_value_as_latin1;
379
 
    if($node->literal_value_language) {
380
 
      $node_label.="@".$node->literal_value_language;
381
 
    }
382
 
    if($node->literal_datatype && 
383
 
       !$node->literal_value_is_wf_xml) {
384
 
      $node_label.="^^&lt;".$node->literal_datatype->as_string."&gt;";
385
 
    }
386
 
  } elsif ($node->is_blank) {
387
 
    $node_label="blank node ".$node->blank_identifier;
388
 
  } else {
389
 
    $node_label=$node ? $node->as_string : "undef";
390
 
  } 
391
 
  $node_label;
392
 
}
393
 
 
394
 
sub print_bindings_results($) {
395
 
  my $results=shift;
396
 
 
397
 
  print qq{<p>Variable bindings result format</p>\n\n};
398
 
 
399
 
  my $width=$results->bindings_count;
400
 
  my $count=0;
401
 
  my(@variables)=();
402
 
  for(my $i=0; $i < $width; $i++) {
403
 
    my $name=$results->binding_name($i);
404
 
    push(@variables, $name) if $name;
405
 
  }
406
 
  
407
 
  if(@variables) {
408
 
    my $t=join('</th> <th>', @variables);
409
 
    print <<"EOT";
410
 
<center>
411
 
<table align="center" border="1">
412
 
<tr>
413
 
<th>Count</th>
414
 
<th>$t</th>
415
 
 
416
 
</tr>
417
 
EOT
418
 
 
419
 
    while(!$results->finished) {
420
 
      $count++;
421
 
      
422
 
      print qq{<tr><td>$count</td>\n};
423
 
      for(my $i=0; $i < $results->bindings_count; $i++) {
424
 
        my $label=format_node($results->binding_value($i));
425
 
        print "<td>$label</td>";
426
 
      }
427
 
      print "</tr>\n";
428
 
      $results->next_result;
429
 
      
430
 
      if ($count >= $max_result_size) {
431
 
        my $w=$width+1;
432
 
        print << "EOT";
433
 
<tr>
434
 
<td colspan="$w">Truncated at $max_result_size items.</td>
435
 
</tr>
436
 
EOT
437
 
        last;
438
 
      }
439
 
    }
440
 
    $results=undef;
441
 
 
442
 
    print <<"EOT";
443
 
</table>
444
 
</center>
445
 
EOT
446
 
  } # end if variables
447
 
 
448
 
  my $pl=($count != 1) ? 's' : '';
449
 
  print "\n\n<p>Found $count result$pl</p>\n";
450
 
}
451
 
 
452
 
 
453
 
sub print_graph_results($) {
454
 
  my $results=shift;
455
 
  my $stream=$results->as_stream;
456
 
 
457
 
  print qq{<p>Graph result format</p>\n\n};
458
 
 
459
 
  print <<"EOT";
460
 
<center>
461
 
<table align="center" border="1">
462
 
<tr>
463
 
<th>Subject</th>
464
 
<th>Predicate</th>
465
 
<th>Object</th>
466
 
</tr>
467
 
EOT
468
 
 
469
 
  my $count=0;
470
 
  for(;!$stream->end ;  $stream->next) {
471
 
    my $statement=$stream->current;
472
 
    
473
 
    last if !$statement;
474
 
    
475
 
    my $subject_label=format_node($statement->subject);
476
 
    my $predicate_label=format_node($statement->predicate);
477
 
    my $object_label=format_node($statement->object);
478
 
    
479
 
    print << "EOT";
480
 
<tr>
481
 
<td>$subject_label</td>
482
 
<td>$predicate_label</td>
483
 
<td>$object_label</td>
484
 
</tr>
485
 
EOT
486
 
 
487
 
    $count++;
488
 
    if ($count >= $max_stream_size) {
489
 
      print << "EOT";
490
 
<tr>
491
 
<td colspan="3">Truncated at $max_stream_size items - sorry, this is just a demonstration.</td>
492
 
</tr>
493
 
EOT
494
 
      last;
495
 
    }
496
 
 
497
 
  } # while
498
 
 
499
 
 
500
 
  print <<"EOT";
501
 
</table>
502
 
</center>
503
 
EOT
504
 
 
505
 
  my $pl=($count != 1) ? 's' : '';
506
 
  print "\n\n<p>Found $count triple$pl</p>\n";
507
 
 
508
 
}
509
 
 
510
 
 
511
 
sub print_boolean_results($) {
512
 
  my $results=shift;
513
 
 
514
 
  print qq{<p>Boolean result format</p>\n\n};
515
 
 
516
 
  my $bresult=$results->get_boolean;
517
 
  print "<p>Result: ",$bresult ? "True" : "False","</p>\n\n";
518
 
}    
519
 
 
520
 
 
521
 
######################################################################
522
 
# Main code
523
 
 
524
 
my $q = new CGI;
525
 
 
526
 
# CGI parameter paranoia
527
 
my $val;
528
 
 
529
 
my $uri_string;
530
 
$val=$q->param('uri');
531
 
if(defined $val && $val =~ /^([ -~]+)$/) {
532
 
  $uri_string=$1;
533
 
} else {
534
 
  $uri_string=undef;
535
 
}
536
 
 
537
 
my $query_string='';
538
 
$val=$q->param('query');
539
 
if(defined $val && $val =~ /^(.*)$/s) {
540
 
  $query_string=$1;
541
 
}
542
 
 
543
 
my $query_language=$default_query_language;
544
 
$val=$q->param('language');
545
 
if(defined $val && $val =~ /^(rdql|sparql)$/s) {
546
 
  $query_language=$1;
547
 
}
548
 
 
549
 
my $raw=0;
550
 
$val=$q->param('raw');
551
 
if(defined $val && $val =~ /^(0|1)$/s) {
552
 
  $raw=$1;
553
 
}
554
 
 
555
 
my $qname=1;
556
 
 
557
 
# End of parameter decoding
558
 
 
559
 
 
560
 
my $execute='yes';
561
 
$val=$q->param('execute');
562
 
if(defined $val && $val eq 'no') {
563
 
  $execute='no';
564
 
}
565
 
 
566
 
# Used in logging
567
 
my $host=$q->remote_host;
568
 
 
569
 
 
570
 
######################################################################
571
 
# Emit content
572
 
 
573
 
print $q->header(-type  =>  'text/html', -charset=>'utf-8');
574
 
 
575
 
 
576
 
# Always print header
577
 
print <<"EOT";
578
 
<?xml version="1.0" encoding="utf-8"?>
579
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
580
 
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
581
 
<head>
582
 
  <title>Redland Rasqal RDF Query Demonstration</title>
583
 
  <!-- HTML STYLE -->
584
 
</head>
585
 
<body>
586
 
 
587
 
<!-- LOGO START -->
588
 
<h1>Redland Rasqal RDF Query Demonstration</h1>
589
 
<!-- LOGO END -->
590
 
 
591
 
<p>This is a demonstration of using
592
 
<a href="http://librdf.org/rasqal/">Rasqal</a>
593
 
to perform queries in either of the RDQL or SPARQL languages over RDF data.
594
 
The data is loaded into a <a href="/">Redland</a> model and then 
595
 
queried and results accessed via the
596
 
<a href="http://librdf.org/docs/perl.html">Redland Perl</a>
597
 
language binding.
598
 
</p>
599
 
 
600
 
EOT
601
 
 
602
 
# use q->url() to get URL of this script without any query parameters
603
 
# since we are using a POST here and don't want them added to the
604
 
# submission URL.
605
 
#my $action_url="/".$q->url(-relative=>1);
606
 
my $action_url="/query";
607
 
 
608
 
my $query_language_label=$query_language_labels{$query_language};
609
 
 
610
 
if($execute eq 'no') {
611
 
  print <<"EOT";
612
 
<div>
613
 
<table border="0" cellspacing="0" cellpadding="0" summary="Main navigation" width="100%" summary="" class="headingbox">
614
 
<tr>
615
 
<td class="mainnavback"><a class="mainnavlink" href="/query?language=rdql">Query with RDQL</a></td>
616
 
<td class="mainnavback"><a class="mainnavlink" href="/query?language=sparql">Query with SPARQL</a></td>
617
 
</tr>
618
 
</table>
619
 
</div>
620
 
EOT
621
 
}
622
 
 
623
 
print <<"EOT";
624
 
<p>Firstly choose whether to query in
625
 
<a href="/query?language=rdql">RDQL</a> or
626
 
<a href="/query?language=sparql">SPARQL</a>, then
627
 
enter a URI of some RDF content to query and run it.
628
 
The example query is for FOAF and finds the
629
 
names of all the people in the graph.  There are other example
630
 
queries further down the page.</p>
631
 
 
632
 
<p>Some RDF content you can use could be my FOAF file at:
633
 
$example_foaf_uri<br />
634
 
or the W3C\'s RSS 1.0 file at:
635
 
$example_rss_uri</p>
636
 
 
637
 
EOT
638
 
print $q->start_form(-method=>'GET', -action => $action_url, -name => 'myform'),"\n";
639
 
print "<p><em>RDF content URIs</em><br/>\n";
640
 
print $q->textfield(-name=>'uri',
641
 
                      -default=>'',
642
 
                      -size=>100,
643
 
                      -maxlength=>1024);
644
 
my $examples=$query_examples{$query_language};
645
 
 
646
 
print "</p>\n\n<p><em>Query</em><br/>\n";
647
 
print $q->textarea(-name=>'query',
648
 
                    -default=>$examples->[0]->{Q},
649
 
                    -columns=>100,
650
 
                    -rows=>10);
651
 
 
652
 
print "</p>\n\n<p>in query language:\n";
653
 
print $q->radio_group(-name=>'language', 
654
 
                        -values=>\@query_languages,
655
 
                        -default=>$default_query_language, 
656
 
                        -labels=>\%query_language_labels);
657
 
 
658
 
print "&nbsp;&nbsp;";
659
 
print $q->checkbox(-name=>'raw',
660
 
                   -checked=>0,
661
 
                   -value=>'1',
662
 
                   -label=>'raw syntax output');
663
 
 
664
 
print "</p>\n\n<p>";
665
 
 
666
 
print $q->submit('Run Query'),"\n";
667
 
print qq{<input type="button" value="Clear Query" onclick="document.myform.query.value=''" />\n};
668
 
 
669
 
print "</p>\n";
670
 
print $q->endform,"\n";
671
 
 
672
 
 
673
 
if($query_string && $uri_string) {
674
 
  print <<"EOT";
675
 
<p>See example queries at the
676
 
<a href="$action_url">Rasqal Query Demonstration home</a></p>
677
 
EOT
678
 
} else {
679
 
  shift(@{$examples});
680
 
 
681
 
  my $query_blurb=$query_blurbs{$query_language};
682
 
 
683
 
  print <<"EOT";
684
 
$query_blurb
685
 
  
686
 
  <p>Some other $query_language_label example queries:</p>
687
 
<ol>
688
 
EOT
689
 
  for my $qe (@{$examples}) {
690
 
    my $t=$qe->{T} || '';
691
 
    my $d=$qe->{D};
692
 
    $t="<em>$t</em><br />\n" if $t;
693
 
    print "<li>${t}Data: $d<br />\nQuery:";
694
 
    print "<pre>\n". html_escape($qe->{Q}) ."</pre>\n";
695
 
 
696
 
    $q->param('uri', $d);
697
 
    $q->param('query', $qe->{Q});    
698
 
    $q->param('language', $query_language);
699
 
    my $query_uri=$q->self_url;
700
 
    print qq{<a href="$query_uri">Run this query</a>\n};
701
 
 
702
 
    print "</li>\n\n";
703
 
  }
704
 
 
705
 
  print <<"EOT";
706
 
</ol>
707
 
EOT
708
 
 
709
 
}
710
 
 
711
 
 
712
 
# Any parameters?
713
 
 
714
 
if(!$q->param) {
715
 
  end_page($q);
716
 
  exit 0;
717
 
}
718
 
 
719
 
if(!$query_string || !$uri_string) {
720
 
  if ($query_string || $uri_string) {
721
 
    print "<hr />\n\n<h2>Error</h2>\n";
722
 
    print "\n\n<p>Got a query string but no RDF content URIs.</p>\n" 
723
 
      if $query_string;
724
 
    print "\n\n<p>Got RDF content URIs but no query string.</p>\n" 
725
 
      if $uri_string;
726
 
  }
727
 
  end_page($q);
728
 
  exit 0;
729
 
}
730
 
 
731
 
print "<hr />\n\n<h2>Results</h2>\n";
732
 
 
733
 
######################################################################
734
 
 
735
 
# Validate me
736
 
if($execute eq 'no') {
737
 
  end_page($q);
738
 
  exit 0;
739
 
}
740
 
 
741
 
my $model=undef;
742
 
my $storage=undef;
743
 
 
744
 
my $db='temp';
745
 
my $store_type="hashes";
746
 
my $options=join(',' , "contexts='yes'", "hash-type='memory'");
747
 
 
748
 
my(@errors)=();
749
 
my(@warnings)=();
750
 
 
751
 
my $handler=sub {
752
 
  my($code, $level, $facility, $message, $line, $column, $byte, $file, $uri)=@_;
753
 
  if($level < 4) {
754
 
    push(@warnings, [$message, $line]);
755
 
  } else {
756
 
    push(@errors, [$message, $line]);
757
 
  }
758
 
 
759
 
  #print "code $code\n";
760
 
  #print "level $level\n";
761
 
  #print "facility $facility\n";
762
 
  #print "message: $message\n" if defined $message;
763
 
  #print "line $line\n";
764
 
  #print "column $column\n";
765
 
  #print "byte $byte\n";
766
 
  #print "file $file\n" if defined $file;
767
 
  #print "uri $uri\n" if defined $uri;
768
 
};
769
 
 
770
 
RDF::Redland::set_log_handler($handler);
771
 
 
772
 
 
773
 
$storage=new RDF::Redland::Storage($store_type, $db, $options);
774
 
if($storage) {
775
 
  $model=new RDF::Redland::Model($storage, "");
776
 
}
777
 
if(!$storage && !$model) {
778
 
  log_action($host, $db, "Failed to open database");
779
 
  print "\n\n<p>Sorry - failed to open RDF Database.  This problem has been recorded.</p>\n";
780
 
  end_page($q);
781
 
  exit 0;
782
 
}
783
 
 
784
 
 
785
 
my $uri=undef;
786
 
if($uri_string) {
787
 
  for my $u (split(/ /, $uri_string)) {
788
 
    if($u !~ /^(ftp|http):/i) {
789
 
      push(@warnings, ["Ignored non-ftp/http URI $u", 0]);
790
 
      next;
791
 
    }
792
 
 
793
 
    $uri=new RDF::Redland::URI($u);
794
 
    my $parser=new RDF::Redland::Parser("guess");
795
 
    eval { $parser->parse_into_model($uri, $uri, $model); };
796
 
    if($@ || @errors) {
797
 
      my $err=join("<br />", map {$_->[0]} @errors);
798
 
      print "\n\n<p><b>Loading URI $u failed with errors:</b><br />\n$err</p>\n";
799
 
      end_page($q);
800
 
      exit 0;
801
 
    }
802
 
    $parser=undef;
803
 
  }
804
 
}
805
 
 
806
 
my $statement=undef;
807
 
my $stream=undef;
808
 
 
809
 
my(@context_nodes);
810
 
 
811
 
if(!$query_string || !$uri_string) {
812
 
  end_page($q);
813
 
  exit 0;
814
 
}
815
 
 
816
 
log_action($host, $db, "Data $uri_string with query '$query_string' in language $query_language");
817
 
if($query_string =~ m%\s+(from)\s+%i) {
818
 
  my $fr=$1;
819
 
  log_action($host, $db, "Query '$query_string' contains 'from' - ignoring it");
820
 
  print "\n\n<p>The query string contains '$fr'; ignoring it</p>\n";
821
 
  end_page($q);
822
 
  exit 0;
823
 
}
824
 
 
825
 
 
826
 
@errors=();
827
 
 
828
 
my $query=undef;
829
 
my $base_uri=new RDF::Redland::URI("http://librdf.org/query");
830
 
eval '$query=new RDF::Redland::Query($query_string, $base_uri, undef, $query_language);';
831
 
if($@ || @errors || !$query) {
832
 
  my $err=join("<br />", map {$_->[1].":".$_->[0]} @errors);
833
 
  print "\n\n<p><b>$query_language_label query construction failed with errors:</b><br />\n$err</p>\n";
834
 
  end_page($q);
835
 
  exit 0;
836
 
}
837
 
$base_uri=undef;
838
 
 
839
 
$q->delete('command');
840
 
$q->delete('query');
841
 
$q->delete('language');
842
 
 
843
 
my $results=undef;
844
 
eval '$results=$model->query_execute($query);';
845
 
if($@ || @errors || !$results) {
846
 
  my $err=join("<br />", map {$_->[1].":".$_->[0]} @errors);
847
 
  print "\n\n<p><b>$query_language_label query execution failed with errors:</b><br />\n$err</p>\n";
848
 
  end_page($q);
849
 
  exit 0;
850
 
}
851
 
 
852
 
if(@warnings) {
853
 
  my $w=join("<br />", map {$_->[1].":".$_->[0]} @warnings);
854
 
  print "<p><b>$query_language_label warnings:</b><br />\n$w</p>\n";
855
 
}
856
 
 
857
 
 
858
 
if($raw) {
859
 
  my $base_uri=new RDF::Redland::URI('http://librdf.org/query/');
860
 
  my $str=$results->to_string;
861
 
 
862
 
  if(defined $str) {
863
 
    print qq{<pre>\n} . html_escape($str) .qq{\n</pre>\n};
864
 
  } else {
865
 
    print qq{<p>No raw format returned\n</p>};
866
 
  }
867
 
 
868
 
} else {
869
 
 
870
 
  if($results->is_bindings) {
871
 
    print_bindings_results($results);
872
 
  } elsif($results->is_graph) {
873
 
    print_graph_results($results);
874
 
  } elsif($results->is_boolean) {
875
 
    print_boolean_results($results);
876
 
  } else {
877
 
    print qq{<p>Unknown results format - cannot display</p>\n\n};
878
 
  }
879
 
  
880
 
}
881
 
 
882
 
end_page($q);
883
 
exit 0;