annotate rdf/SimpleSPARQLQuery.cpp @ 493:3931711b5671

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