annotate rdf/SimpleSPARQLQuery.cpp @ 500:83eae5239db6

* Permit viewing (though not editing) colour 3d plot layer data in the spreadsheet data viewer dialog * Add somewhat simplistic RDF export for layers * Fix display of peak frequencies in spectrum layer * Fix (I hope) sizing of plugin parameter dialog
author Chris Cannam
date Tue, 02 Dec 2008 17:17:25 +0000
parents 438f4e295a9c
children db398832518b
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@495 81 std::cerr << "SimpleSPARQLQuery: WARNING: 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@494 519 const char *lit = (const char *)librdf_node_get_literal_value(node);
Chris@494 520 if (lit) text = lit;
Chris@494 521
Chris@481 522 } else {
Chris@481 523
Chris@480 524 cerr << "SimpleSPARQLQuery: LIBRDF query returned unknown node type (not resource, literal, or blank)" << endl;
Chris@480 525 }
Chris@480 526
Chris@480 527 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@481 528 cerr << i << ". " << key.toStdString() << " -> " << text.toStdString() << " (type " << type << ")" << endl;
Chris@480 529 #endif
Chris@480 530
Chris@480 531 resultmap[key] = Value(type, text);
Chris@480 532
Chris@492 533 // librdf_free_node(node);
Chris@480 534 }
Chris@480 535
Chris@480 536 list.push_back(resultmap);
Chris@480 537
Chris@480 538 librdf_query_results_next(results);
Chris@480 539
Chris@480 540 resultCount++;
Chris@480 541
Chris@480 542 if (m_reporter) {
Chris@480 543 if (resultCount >= resultTotal) {
Chris@480 544 if (m_reporter->isDefinite()) m_reporter->setDefinite(false);
Chris@480 545 m_reporter->setProgress(resultCount);
Chris@480 546 } else {
Chris@480 547 m_reporter->setProgress((resultCount * 100) / resultTotal);
Chris@480 548 }
Chris@480 549
Chris@480 550 if (m_reporter->wasCancelled()) {
Chris@480 551 m_cancelled = true;
Chris@480 552 break;
Chris@480 553 }
Chris@480 554 }
Chris@480 555 }
Chris@480 556
Chris@480 557 librdf_free_query_results(results);
Chris@480 558 librdf_free_query(query);
Chris@480 559
Chris@481 560 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 561 cerr << "SimpleSPARQLQuery::executeDatastore: All results retrieved (" << resultCount << " of them)" << endl;
Chris@481 562 #endif
Chris@480 563
Chris@480 564 return list;
Chris@489 565 }
Chris@489 566
Chris@489 567 bool
Chris@489 568 SimpleSPARQLQuery::Impl::addSourceToModel(QString sourceUri)
Chris@489 569 {
Chris@489 570 QString err;
Chris@489 571
Chris@490 572 QMutexLocker locker(&m_mutex);
Chris@489 573
Chris@492 574 if (!m_redland.isOK()) {
Chris@492 575 std::cerr << "SimpleSPARQLQuery::addSourceToModel: Failed to initialise Redland datastore" << std::endl;
Chris@492 576 return false;
Chris@489 577 }
Chris@489 578
Chris@492 579 if (!m_redland.loadUriIntoDefaultModel(sourceUri, err)) {
Chris@489 580 std::cerr << "SimpleSPARQLQuery::addSourceToModel: Failed to add source URI \"" << sourceUri.toStdString() << ": " << err.toStdString() << std::endl;
Chris@489 581 return false;
Chris@489 582 }
Chris@489 583 return true;
Chris@480 584 }
Chris@480 585
Chris@492 586 void
Chris@492 587 SimpleSPARQLQuery::Impl::closeSingleSource(QString sourceUri)
Chris@492 588 {
Chris@492 589 QMutexLocker locker(&m_mutex);
Chris@492 590
Chris@492 591 m_redland.freeModel(sourceUri);
Chris@492 592 }
Chris@492 593
Chris@440 594 SimpleSPARQLQuery::Value
Chris@489 595 SimpleSPARQLQuery::singleResultQuery(QueryType type,
Chris@480 596 QString query, QString binding)
Chris@440 597 {
Chris@489 598 SimpleSPARQLQuery q(type, query);
Chris@440 599 ResultList results = q.execute();
Chris@440 600 if (!q.isOK()) {
Chris@440 601 cerr << "SimpleSPARQLQuery::singleResultQuery: ERROR: "
Chris@440 602 << q.getErrorString().toStdString() << endl;
Chris@440 603 return Value();
Chris@440 604 }
Chris@440 605 if (results.empty()) {
Chris@440 606 return Value();
Chris@440 607 }
Chris@440 608 for (int i = 0; i < results.size(); ++i) {
Chris@440 609 if (results[i].find(binding) != results[i].end() &&
Chris@440 610 results[i][binding].type != NoValue) {
Chris@440 611 return results[i][binding];
Chris@440 612 }
Chris@440 613 }
Chris@440 614 return Value();
Chris@440 615 }
Chris@440 616
Chris@440 617
Chris@440 618