annotate rdf/SimpleSPARQLQuery.cpp @ 717:bcdb2a18d9bc library_integration

Revert that change -- this code is used only in Sonic Annotator
author Chris Cannam
date Tue, 18 Oct 2011 10:14:17 +0100
parents 97fbb6b3e749
children f3fd2988fc9b
rev   line source
Chris@439 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@439 2
Chris@439 3 /*
Chris@439 4 Sonic Visualiser
Chris@439 5 An audio file viewer and annotation editor.
Chris@439 6 Centre for Digital Music, Queen Mary, University of London.
Chris@439 7 This file copyright 2008 QMUL.
Chris@439 8
Chris@439 9 This program is free software; you can redistribute it and/or
Chris@439 10 modify it under the terms of the GNU General Public License as
Chris@439 11 published by the Free Software Foundation; either version 2 of the
Chris@439 12 License, or (at your option) any later version. See the file
Chris@439 13 COPYING included with this distribution for more information.
Chris@439 14 */
Chris@439 15
Chris@439 16 #include "SimpleSPARQLQuery.h"
Chris@439 17 #include "base/ProgressReporter.h"
Chris@480 18 #include "base/Profiler.h"
Chris@480 19
Chris@480 20 #include <QMutex>
Chris@480 21 #include <QMutexLocker>
Chris@481 22 #include <QRegExp>
Chris@480 23
Chris@480 24 #include <set>
Chris@439 25
Chris@644 26 // Rather than including <redland.h> -- for some reason redland.h
Chris@644 27 // includes <rasqal.h>, while the rasqal header actually gets
Chris@644 28 // installed as <rasqal/rasqal.h> which breaks the inclusion all over
Chris@644 29 // the place unless a very clever include path is set
Chris@644 30 #include <rasqal/rasqal.h>
Chris@644 31 #include <librdf.h>
Chris@480 32
Chris@492 33 //#define DEBUG_SIMPLE_SPARQL_QUERY 1
Chris@461 34
Chris@439 35 #include <iostream>
Chris@439 36
Chris@439 37 using std::cerr;
Chris@439 38 using std::endl;
Chris@439 39
Chris@480 40 class WredlandWorldWrapper
Chris@480 41 {
Chris@480 42 public:
Chris@492 43 WredlandWorldWrapper();
Chris@492 44 ~WredlandWorldWrapper();
Chris@480 45
Chris@492 46 bool isOK() const;
Chris@480 47
Chris@492 48 bool loadUriIntoDefaultModel(QString uriString, QString &errorString);
Chris@480 49
Chris@480 50 librdf_world *getWorld() { return m_world; }
Chris@480 51 const librdf_world *getWorld() const { return m_world; }
Chris@480 52
Chris@492 53 librdf_model *getDefaultModel() { return m_defaultModel; }
Chris@492 54 const librdf_model *getDefaultModel() const { return m_defaultModel; }
Chris@492 55
Chris@492 56 librdf_model *getModel(QString fromUri);
Chris@492 57 void freeModel(QString forUri);
Chris@480 58
Chris@480 59 private:
Chris@492 60 QMutex m_mutex;
Chris@492 61
Chris@480 62 librdf_world *m_world;
Chris@492 63 librdf_storage *m_defaultStorage;
Chris@492 64 librdf_model *m_defaultModel;
Chris@480 65
Chris@492 66 std::set<QString> m_defaultModelUris;
Chris@492 67
Chris@492 68 std::map<QString, librdf_storage *> m_ownStorageUris;
Chris@492 69 std::map<QString, librdf_model *> m_ownModelUris;
Chris@492 70
Chris@492 71 bool loadUri(librdf_model *model, QString uri, QString &errorString);
Chris@480 72 };
Chris@480 73
Chris@492 74 WredlandWorldWrapper::WredlandWorldWrapper() :
Chris@492 75 m_world(0), m_defaultStorage(0), m_defaultModel(0)
Chris@492 76 {
Chris@492 77 m_world = librdf_new_world();
Chris@492 78 if (!m_world) {
Chris@492 79 cerr << "SimpleSPARQLQuery: ERROR: Failed to create LIBRDF world!" << endl;
Chris@492 80 return;
Chris@492 81 }
Chris@492 82 librdf_world_open(m_world);
Chris@492 83
Chris@492 84 m_defaultStorage = librdf_new_storage(m_world, "trees", NULL, NULL);
Chris@492 85 if (!m_defaultStorage) {
Chris@495 86 std::cerr << "SimpleSPARQLQuery: WARNING: Failed to initialise Redland trees datastore, falling back to memory store" << std::endl;
Chris@492 87 m_defaultStorage = librdf_new_storage(m_world, NULL, NULL, NULL);
Chris@492 88 if (!m_defaultStorage) {
Chris@492 89 std::cerr << "SimpleSPARQLQuery: ERROR: Failed to initialise Redland memory datastore" << std::endl;
Chris@492 90 return;
Chris@492 91 }
Chris@492 92 }
Chris@492 93 m_defaultModel = librdf_new_model(m_world, m_defaultStorage, NULL);
Chris@492 94 if (!m_defaultModel) {
Chris@492 95 std::cerr << "SimpleSPARQLQuery: ERROR: Failed to initialise Redland data model" << std::endl;
Chris@492 96 return;
Chris@492 97 }
Chris@492 98 }
Chris@492 99
Chris@492 100 WredlandWorldWrapper::~WredlandWorldWrapper()
Chris@492 101 {
Chris@505 102 /*!!! This is a static singleton; destroying it while there are
Chris@505 103 queries outstanding can be problematic, it appears, and since
Chris@505 104 the storage is non-persistent there shouldn't be any need to
Chris@505 105 destroy it explicitly, except for the sake of tidiness.
Chris@505 106
Chris@492 107 while (!m_ownModelUris.empty()) {
Chris@492 108 librdf_free_model(m_ownModelUris.begin()->second);
Chris@492 109 m_ownModelUris.erase(m_ownModelUris.begin());
Chris@492 110 }
Chris@492 111 while (!m_ownStorageUris.empty()) {
Chris@492 112 librdf_free_storage(m_ownStorageUris.begin()->second);
Chris@492 113 m_ownStorageUris.erase(m_ownStorageUris.begin());
Chris@492 114 }
Chris@492 115 if (m_defaultModel) librdf_free_model(m_defaultModel);
Chris@492 116 if (m_defaultStorage) librdf_free_storage(m_defaultStorage);
Chris@492 117 if (m_world) librdf_free_world(m_world);
Chris@505 118 */
Chris@492 119 }
Chris@492 120
Chris@492 121 bool
Chris@492 122 WredlandWorldWrapper::isOK() const {
Chris@492 123 return (m_defaultModel != 0);
Chris@492 124 }
Chris@492 125
Chris@492 126 bool
Chris@492 127 WredlandWorldWrapper::loadUriIntoDefaultModel(QString uriString, QString &errorString)
Chris@492 128 {
Chris@492 129 QMutexLocker locker(&m_mutex);
Chris@492 130
Chris@492 131 if (m_defaultModelUris.find(uriString) != m_defaultModelUris.end()) {
Chris@492 132 return true;
Chris@492 133 }
Chris@492 134
Chris@492 135 if (loadUri(m_defaultModel, uriString, errorString)) {
Chris@492 136 m_defaultModelUris.insert(uriString);
Chris@492 137 return true;
Chris@492 138 } else {
Chris@492 139 return false;
Chris@492 140 }
Chris@492 141 }
Chris@492 142
Chris@492 143 librdf_model *
Chris@492 144 WredlandWorldWrapper::getModel(QString fromUri)
Chris@492 145 {
Chris@492 146 QMutexLocker locker(&m_mutex);
Chris@492 147 if (fromUri == "") {
Chris@492 148 return getDefaultModel();
Chris@492 149 }
Chris@492 150 if (m_ownModelUris.find(fromUri) != m_ownModelUris.end()) {
Chris@492 151 return m_ownModelUris[fromUri];
Chris@492 152 }
Chris@492 153 librdf_storage *storage = librdf_new_storage(m_world, "trees", NULL, NULL);
Chris@492 154 if (!storage) { // don't warn here, we probably already did it in main ctor
Chris@492 155 storage = librdf_new_storage(m_world, NULL, NULL, NULL);
Chris@492 156 }
Chris@492 157 librdf_model *model = librdf_new_model(m_world, storage, NULL);
Chris@492 158 if (!model) {
Chris@492 159 std::cerr << "SimpleSPARQLQuery: ERROR: Failed to create new model" << std::endl;
Chris@492 160 librdf_free_storage(storage);
Chris@492 161 return 0;
Chris@492 162 }
Chris@492 163 QString err;
Chris@492 164 if (!loadUri(model, fromUri, err)) {
Chris@686 165 std::cerr << "SimpleSPARQLQuery: ERROR: Failed to parse into new model: " << err << std::endl;
Chris@492 166 librdf_free_model(model);
Chris@492 167 librdf_free_storage(storage);
Chris@492 168 m_ownModelUris[fromUri] = 0;
Chris@492 169 return 0;
Chris@492 170 }
Chris@492 171 m_ownModelUris[fromUri] = model;
Chris@492 172 m_ownStorageUris[fromUri] = storage;
Chris@492 173 return model;
Chris@492 174 }
Chris@492 175
Chris@492 176 void
Chris@492 177 WredlandWorldWrapper::freeModel(QString forUri)
Chris@492 178 {
Chris@493 179 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@690 180 SVDEBUG << "SimpleSPARQLQuery::freeModel: Model uri = \"" << forUri << "\"" << endl;
Chris@493 181 #endif
Chris@493 182
Chris@492 183 QMutexLocker locker(&m_mutex);
Chris@492 184 if (forUri == "") {
Chris@690 185 SVDEBUG << "SimpleSPARQLQuery::freeModel: ERROR: Can't free default model" << endl;
Chris@492 186 return;
Chris@492 187 }
Chris@492 188 if (m_ownModelUris.find(forUri) == m_ownModelUris.end()) {
Chris@493 189 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@690 190 SVDEBUG << "SimpleSPARQLQuery::freeModel: NOTE: Unknown or already-freed model (uri = \"" << forUri << "\")" << endl;
Chris@493 191 #endif
Chris@492 192 return;
Chris@492 193 }
Chris@492 194
Chris@492 195 librdf_model *model = m_ownModelUris[forUri];
Chris@492 196 if (model) librdf_free_model(model);
Chris@492 197 m_ownModelUris.erase(forUri);
Chris@492 198
Chris@492 199 if (m_ownStorageUris.find(forUri) != m_ownStorageUris.end()) {
Chris@492 200 librdf_storage *storage = m_ownStorageUris[forUri];
Chris@492 201 if (storage) librdf_free_storage(storage);
Chris@492 202 m_ownStorageUris.erase(forUri);
Chris@492 203 }
Chris@492 204 }
Chris@492 205
Chris@492 206 bool
Chris@492 207 WredlandWorldWrapper::loadUri(librdf_model *model, QString uri, QString &errorString)
Chris@492 208 {
Chris@492 209 librdf_uri *luri = librdf_new_uri
Chris@492 210 (m_world, (const unsigned char *)uri.toUtf8().data());
Chris@492 211 if (!luri) {
Chris@492 212 errorString = "Failed to construct librdf_uri!";
Chris@492 213 return false;
Chris@492 214 }
Chris@492 215
Chris@492 216 librdf_parser *parser = librdf_new_parser(m_world, "guess", NULL, NULL);
Chris@492 217 if (!parser) {
Chris@492 218 errorString = "Failed to initialise Redland parser";
Chris@492 219 return false;
Chris@492 220 }
Chris@507 221
Chris@507 222 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@686 223 std::cerr << "About to parse \"" << uri << "\"" << std::endl;
Chris@507 224 #endif
Chris@492 225
Chris@492 226 Profiler p("SimpleSPARQLQuery: Parse URI into LIBRDF model");
Chris@492 227
Chris@492 228 if (librdf_parser_parse_into_model(parser, luri, NULL, model)) {
Chris@492 229
Chris@492 230 errorString = QString("Failed to parse RDF from URI \"%1\"")
Chris@492 231 .arg(uri);
Chris@492 232 librdf_free_parser(parser);
Chris@492 233 return false;
Chris@492 234
Chris@492 235 } else {
Chris@492 236
Chris@492 237 librdf_free_parser(parser);
Chris@492 238 return true;
Chris@492 239 }
Chris@492 240 }
Chris@492 241
Chris@492 242
Chris@439 243 class SimpleSPARQLQuery::Impl
Chris@439 244 {
Chris@439 245 public:
Chris@489 246 Impl(SimpleSPARQLQuery::QueryType, QString query);
Chris@439 247 ~Impl();
Chris@439 248
Chris@489 249 static bool addSourceToModel(QString sourceUri);
Chris@492 250 static void closeSingleSource(QString sourceUri);
Chris@489 251
Chris@439 252 void setProgressReporter(ProgressReporter *reporter) { m_reporter = reporter; }
Chris@439 253 bool wasCancelled() const { return m_cancelled; }
Chris@439 254
Chris@439 255 ResultList execute();
Chris@439 256
Chris@439 257 bool isOK() const;
Chris@439 258 QString getErrorString() const;
Chris@439 259
Chris@439 260 protected:
Chris@480 261 static QMutex m_mutex;
Chris@480 262
Chris@526 263 static WredlandWorldWrapper *m_redland;
Chris@480 264
Chris@480 265 ResultList executeDirectParser();
Chris@480 266 ResultList executeDatastore();
Chris@492 267 ResultList executeFor(QString modelUri);
Chris@480 268
Chris@489 269 QueryType m_type;
Chris@439 270 QString m_query;
Chris@439 271 QString m_errorString;
Chris@439 272 ProgressReporter *m_reporter;
Chris@439 273 bool m_cancelled;
Chris@439 274 };
Chris@439 275
Chris@526 276 WredlandWorldWrapper *SimpleSPARQLQuery::Impl::m_redland = 0;
Chris@480 277
Chris@480 278 QMutex SimpleSPARQLQuery::Impl::m_mutex;
Chris@480 279
Chris@489 280 SimpleSPARQLQuery::SimpleSPARQLQuery(QueryType type, QString query) :
Chris@489 281 m_impl(new Impl(type, query))
Chris@480 282 {
Chris@480 283 }
Chris@439 284
Chris@439 285 SimpleSPARQLQuery::~SimpleSPARQLQuery()
Chris@439 286 {
Chris@439 287 delete m_impl;
Chris@439 288 }
Chris@439 289
Chris@439 290 void
Chris@439 291 SimpleSPARQLQuery::setProgressReporter(ProgressReporter *reporter)
Chris@439 292 {
Chris@439 293 m_impl->setProgressReporter(reporter);
Chris@439 294 }
Chris@439 295
Chris@439 296 bool
Chris@439 297 SimpleSPARQLQuery::wasCancelled() const
Chris@439 298 {
Chris@439 299 return m_impl->wasCancelled();
Chris@439 300 }
Chris@439 301
Chris@439 302 SimpleSPARQLQuery::ResultList
Chris@439 303 SimpleSPARQLQuery::execute()
Chris@439 304 {
Chris@439 305 return m_impl->execute();
Chris@439 306 }
Chris@439 307
Chris@439 308 bool
Chris@439 309 SimpleSPARQLQuery::isOK() const
Chris@439 310 {
Chris@439 311 return m_impl->isOK();
Chris@439 312 }
Chris@439 313
Chris@439 314 QString
Chris@439 315 SimpleSPARQLQuery::getErrorString() const
Chris@439 316 {
Chris@439 317 return m_impl->getErrorString();
Chris@439 318 }
Chris@439 319
Chris@489 320 bool
Chris@489 321 SimpleSPARQLQuery::addSourceToModel(QString sourceUri)
Chris@480 322 {
Chris@489 323 return SimpleSPARQLQuery::Impl::addSourceToModel(sourceUri);
Chris@480 324 }
Chris@480 325
Chris@492 326 void
Chris@492 327 SimpleSPARQLQuery::closeSingleSource(QString sourceUri)
Chris@492 328 {
Chris@492 329 SimpleSPARQLQuery::Impl::closeSingleSource(sourceUri);
Chris@492 330 }
Chris@492 331
Chris@489 332 SimpleSPARQLQuery::Impl::Impl(QueryType type, QString query) :
Chris@489 333 m_type(type),
Chris@439 334 m_query(query),
Chris@439 335 m_reporter(0),
Chris@439 336 m_cancelled(false)
Chris@439 337 {
Chris@439 338 }
Chris@439 339
Chris@439 340 SimpleSPARQLQuery::Impl::~Impl()
Chris@439 341 {
Chris@439 342 }
Chris@439 343
Chris@439 344 bool
Chris@439 345 SimpleSPARQLQuery::Impl::isOK() const
Chris@439 346 {
Chris@439 347 return (m_errorString == "");
Chris@439 348 }
Chris@439 349
Chris@439 350 QString
Chris@439 351 SimpleSPARQLQuery::Impl::getErrorString() const
Chris@439 352 {
Chris@439 353 return m_errorString;
Chris@439 354 }
Chris@439 355
Chris@439 356 SimpleSPARQLQuery::ResultList
Chris@439 357 SimpleSPARQLQuery::Impl::execute()
Chris@439 358 {
Chris@439 359 ResultList list;
Chris@439 360
Chris@490 361 QMutexLocker locker(&m_mutex);
Chris@480 362
Chris@526 363 if (!m_redland) {
Chris@526 364 m_redland = new WredlandWorldWrapper();
Chris@526 365 }
Chris@526 366
Chris@526 367 if (!m_redland->isOK()) {
Chris@492 368 cerr << "ERROR: SimpleSPARQLQuery::execute: Failed to initialise Redland datastore" << endl;
Chris@492 369 return list;
Chris@440 370 }
Chris@480 371
Chris@489 372 if (m_type == QueryFromSingleSource) {
Chris@480 373 return executeDirectParser();
Chris@480 374 } else {
Chris@480 375 return executeDatastore();
Chris@480 376 }
Chris@492 377
Chris@492 378 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 379 if (m_errorString != "") {
Chris@492 380 std::cerr << "SimpleSPARQLQuery::execute: error returned: \""
Chris@686 381 << m_errorString << "\"" << std::endl;
Chris@492 382 }
Chris@492 383 #endif
Chris@480 384 }
Chris@480 385
Chris@480 386 SimpleSPARQLQuery::ResultList
Chris@480 387 SimpleSPARQLQuery::Impl::executeDirectParser()
Chris@480 388 {
Chris@492 389 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@690 390 SVDEBUG << "SimpleSPARQLQuery::executeDirectParser: Query is: \"" << m_query << "\"" << endl;
Chris@492 391 #endif
Chris@492 392
Chris@480 393 ResultList list;
Chris@480 394
Chris@480 395 Profiler profiler("SimpleSPARQLQuery::executeDirectParser");
Chris@480 396
Chris@492 397 static QRegExp fromRE("from\\s+<([^>]+)>", Qt::CaseInsensitive);
Chris@492 398 QString fromUri;
Chris@492 399
Chris@492 400 if (fromRE.indexIn(m_query) < 0) {
Chris@690 401 SVDEBUG << "SimpleSPARQLQuery::executeDirectParser: Query contains no FROM clause, nothing to parse from" << endl;
Chris@492 402 return list;
Chris@492 403 } else {
Chris@492 404 fromUri = fromRE.cap(1);
Chris@492 405 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@690 406 SVDEBUG << "SimpleSPARQLQuery::executeDirectParser: FROM URI is <"
Chris@687 407 << fromUri << ">" << endl;
Chris@440 408 #endif
Chris@439 409 }
Chris@439 410
Chris@492 411 return executeFor(fromUri);
Chris@439 412 }
Chris@440 413
Chris@480 414 SimpleSPARQLQuery::ResultList
Chris@480 415 SimpleSPARQLQuery::Impl::executeDatastore()
Chris@480 416 {
Chris@492 417 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@690 418 SVDEBUG << "SimpleSPARQLQuery::executeDatastore: Query is: \"" << m_query << "\"" << endl;
Chris@492 419 #endif
Chris@492 420
Chris@480 421 ResultList list;
Chris@489 422
Chris@480 423 Profiler profiler("SimpleSPARQLQuery::executeDatastore");
Chris@480 424
Chris@492 425 return executeFor("");
Chris@492 426 }
Chris@492 427
Chris@492 428 SimpleSPARQLQuery::ResultList
Chris@492 429 SimpleSPARQLQuery::Impl::executeFor(QString modelUri)
Chris@492 430 {
Chris@492 431 ResultList list;
Chris@492 432 librdf_query *query;
Chris@492 433
Chris@493 434 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@480 435 static std::map<QString, int> counter;
Chris@480 436 if (counter.find(m_query) == counter.end()) counter[m_query] = 1;
Chris@480 437 else ++counter[m_query];
Chris@480 438 std::cerr << "Counter for this query: " << counter[m_query] << std::endl;
Chris@686 439 std::cerr << "Base URI is: \"" << modelUri << "\"" << std::endl;
Chris@493 440 #endif
Chris@480 441
Chris@480 442 {
Chris@480 443 Profiler p("SimpleSPARQLQuery: Prepare LIBRDF query");
Chris@480 444 query = librdf_new_query
Chris@526 445 (m_redland->getWorld(), "sparql", NULL,
Chris@489 446 (const unsigned char *)m_query.toUtf8().data(), NULL);
Chris@480 447 }
Chris@480 448
Chris@480 449 if (!query) {
Chris@480 450 m_errorString = "Failed to construct query";
Chris@480 451 return list;
Chris@480 452 }
Chris@480 453
Chris@480 454 librdf_query_results *results;
Chris@480 455 {
Chris@480 456 Profiler p("SimpleSPARQLQuery: Execute LIBRDF query");
Chris@526 457 results = librdf_query_execute(query, m_redland->getModel(modelUri));
Chris@480 458 }
Chris@480 459
Chris@480 460 if (!results) {
Chris@511 461 m_errorString = "RDF query failed";
Chris@480 462 librdf_free_query(query);
Chris@480 463 return list;
Chris@480 464 }
Chris@480 465
Chris@480 466 if (!librdf_query_results_is_bindings(results)) {
Chris@511 467 m_errorString = "RDF query returned non-bindings results";
Chris@480 468 librdf_free_query_results(results);
Chris@480 469 librdf_free_query(query);
Chris@480 470 return list;
Chris@480 471 }
Chris@480 472
Chris@480 473 int resultCount = 0;
Chris@480 474 int resultTotal = librdf_query_results_get_count(results); // probably wrong
Chris@480 475 m_cancelled = false;
Chris@480 476
Chris@480 477 while (!librdf_query_results_finished(results)) {
Chris@480 478
Chris@480 479 int count = librdf_query_results_get_bindings_count(results);
Chris@480 480
Chris@480 481 KeyValueMap resultmap;
Chris@480 482
Chris@480 483 for (int i = 0; i < count; ++i) {
Chris@480 484
Chris@480 485 const char *name =
Chris@480 486 librdf_query_results_get_binding_name(results, i);
Chris@480 487
Chris@490 488 if (!name) {
Chris@490 489 std::cerr << "WARNING: Result " << i << " of query has no name" << std::endl;
Chris@490 490 continue;
Chris@490 491 }
Chris@490 492
Chris@480 493 librdf_node *node =
Chris@480 494 librdf_query_results_get_binding_value(results, i);
Chris@480 495
Chris@480 496 QString key = (const char *)name;
Chris@480 497
Chris@480 498 if (!node) {
Chris@492 499 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@686 500 std::cerr << i << ". " << key << " -> (nil)" << std::endl;
Chris@492 501 #endif
Chris@480 502 resultmap[key] = Value();
Chris@480 503 continue;
Chris@480 504 }
Chris@480 505
Chris@480 506 ValueType type = LiteralValue;
Chris@481 507 QString text;
Chris@481 508
Chris@481 509 if (librdf_node_is_resource(node)) {
Chris@481 510
Chris@481 511 type = URIValue;
Chris@481 512 librdf_uri *uri = librdf_node_get_uri(node);
Chris@490 513 const char *us = (const char *)librdf_uri_as_string(uri);
Chris@490 514
Chris@490 515 if (!us) {
Chris@490 516 std::cerr << "WARNING: Result " << i << " of query claims URI type, but has null URI" << std::endl;
Chris@490 517 } else {
Chris@490 518 text = us;
Chris@490 519 }
Chris@481 520
Chris@481 521 } else if (librdf_node_is_literal(node)) {
Chris@481 522
Chris@481 523 type = LiteralValue;
Chris@490 524
Chris@490 525 const char *lit = (const char *)librdf_node_get_literal_value(node);
Chris@490 526 if (!lit) {
Chris@490 527 std::cerr << "WARNING: Result " << i << " of query claims literal type, but has no literal" << std::endl;
Chris@490 528 } else {
Chris@490 529 text = lit;
Chris@490 530 }
Chris@481 531
Chris@481 532 } else if (librdf_node_is_blank(node)) {
Chris@481 533
Chris@481 534 type = BlankValue;
Chris@481 535
Chris@494 536 const char *lit = (const char *)librdf_node_get_literal_value(node);
Chris@494 537 if (lit) text = lit;
Chris@494 538
Chris@481 539 } else {
Chris@481 540
Chris@480 541 cerr << "SimpleSPARQLQuery: LIBRDF query returned unknown node type (not resource, literal, or blank)" << endl;
Chris@480 542 }
Chris@480 543
Chris@480 544 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@686 545 cerr << i << ". " << key << " -> " << text << " (type " << type << ")" << endl;
Chris@480 546 #endif
Chris@480 547
Chris@480 548 resultmap[key] = Value(type, text);
Chris@480 549
Chris@492 550 // librdf_free_node(node);
Chris@480 551 }
Chris@480 552
Chris@480 553 list.push_back(resultmap);
Chris@480 554
Chris@480 555 librdf_query_results_next(results);
Chris@480 556
Chris@480 557 resultCount++;
Chris@480 558
Chris@480 559 if (m_reporter) {
Chris@480 560 if (resultCount >= resultTotal) {
Chris@480 561 if (m_reporter->isDefinite()) m_reporter->setDefinite(false);
Chris@480 562 m_reporter->setProgress(resultCount);
Chris@480 563 } else {
Chris@480 564 m_reporter->setProgress((resultCount * 100) / resultTotal);
Chris@480 565 }
Chris@480 566
Chris@480 567 if (m_reporter->wasCancelled()) {
Chris@480 568 m_cancelled = true;
Chris@480 569 break;
Chris@480 570 }
Chris@480 571 }
Chris@480 572 }
Chris@480 573
Chris@480 574 librdf_free_query_results(results);
Chris@480 575 librdf_free_query(query);
Chris@480 576
Chris@481 577 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@690 578 SVDEBUG << "SimpleSPARQLQuery::executeDatastore: All results retrieved (" << resultCount << " of them)" << endl;
Chris@481 579 #endif
Chris@480 580
Chris@480 581 return list;
Chris@489 582 }
Chris@489 583
Chris@489 584 bool
Chris@489 585 SimpleSPARQLQuery::Impl::addSourceToModel(QString sourceUri)
Chris@489 586 {
Chris@489 587 QString err;
Chris@489 588
Chris@490 589 QMutexLocker locker(&m_mutex);
Chris@489 590
Chris@527 591 if (!m_redland) {
Chris@527 592 m_redland = new WredlandWorldWrapper();
Chris@527 593 }
Chris@527 594
Chris@526 595 if (!m_redland->isOK()) {
Chris@492 596 std::cerr << "SimpleSPARQLQuery::addSourceToModel: Failed to initialise Redland datastore" << std::endl;
Chris@492 597 return false;
Chris@489 598 }
Chris@489 599
Chris@526 600 if (!m_redland->loadUriIntoDefaultModel(sourceUri, err)) {
Chris@686 601 std::cerr << "SimpleSPARQLQuery::addSourceToModel: Failed to add source URI \"" << sourceUri << ": " << err << std::endl;
Chris@489 602 return false;
Chris@489 603 }
Chris@489 604 return true;
Chris@480 605 }
Chris@480 606
Chris@492 607 void
Chris@492 608 SimpleSPARQLQuery::Impl::closeSingleSource(QString sourceUri)
Chris@492 609 {
Chris@492 610 QMutexLocker locker(&m_mutex);
Chris@492 611
Chris@526 612 m_redland->freeModel(sourceUri);
Chris@492 613 }
Chris@492 614
Chris@440 615 SimpleSPARQLQuery::Value
Chris@489 616 SimpleSPARQLQuery::singleResultQuery(QueryType type,
Chris@480 617 QString query, QString binding)
Chris@440 618 {
Chris@489 619 SimpleSPARQLQuery q(type, query);
Chris@440 620 ResultList results = q.execute();
Chris@440 621 if (!q.isOK()) {
Chris@690 622 SVDEBUG << "SimpleSPARQLQuery::singleResultQuery: ERROR: "
Chris@686 623 << q.getErrorString() << endl;
Chris@440 624 return Value();
Chris@440 625 }
Chris@440 626 if (results.empty()) {
Chris@440 627 return Value();
Chris@440 628 }
Chris@440 629 for (int i = 0; i < results.size(); ++i) {
Chris@440 630 if (results[i].find(binding) != results[i].end() &&
Chris@440 631 results[i][binding].type != NoValue) {
Chris@440 632 return results[i][binding];
Chris@440 633 }
Chris@440 634 }
Chris@440 635 return Value();
Chris@440 636 }
Chris@440 637
Chris@440 638
Chris@440 639