annotate rdf/SimpleSPARQLQuery.cpp @ 492:23945cdd7161

* Update RDF query stuff again so as to set up a temporary datastore each time we want to query over an rdf file, instead of using rasqal against the file. Seems the only way to avoid threading and storage management issues when trying to load from a single-source file and perform queries against our main datastore at the same time. Maybe.
author Chris Cannam
date Mon, 24 Nov 2008 16:26:11 +0000
parents c3fb8258e34d
children 3931711b5671
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@492 168 QMutexLocker locker(&m_mutex);
Chris@492 169 if (forUri == "") {
Chris@492 170 std::cerr << "SimpleSPARQLQuery::freeModel: ERROR: Can't free default model" << std::endl;
Chris@492 171 return;
Chris@492 172 }
Chris@492 173 if (m_ownModelUris.find(forUri) == m_ownModelUris.end()) {
Chris@492 174 std::cerr << "SimpleSPARQLQuery::freeModel: ERROR: Never heard of this model (uri = \"" << forUri.toStdString() << "\")" << std::endl;
Chris@492 175 return;
Chris@492 176 }
Chris@492 177
Chris@492 178 librdf_model *model = m_ownModelUris[forUri];
Chris@492 179 if (model) librdf_free_model(model);
Chris@492 180 m_ownModelUris.erase(forUri);
Chris@492 181
Chris@492 182 if (m_ownStorageUris.find(forUri) != m_ownStorageUris.end()) {
Chris@492 183 librdf_storage *storage = m_ownStorageUris[forUri];
Chris@492 184 if (storage) librdf_free_storage(storage);
Chris@492 185 m_ownStorageUris.erase(forUri);
Chris@492 186 }
Chris@492 187 }
Chris@492 188
Chris@492 189 bool
Chris@492 190 WredlandWorldWrapper::loadUri(librdf_model *model, QString uri, QString &errorString)
Chris@492 191 {
Chris@492 192 librdf_uri *luri = librdf_new_uri
Chris@492 193 (m_world, (const unsigned char *)uri.toUtf8().data());
Chris@492 194 if (!luri) {
Chris@492 195 errorString = "Failed to construct librdf_uri!";
Chris@492 196 return false;
Chris@492 197 }
Chris@492 198
Chris@492 199 librdf_parser *parser = librdf_new_parser(m_world, "guess", NULL, NULL);
Chris@492 200 if (!parser) {
Chris@492 201 errorString = "Failed to initialise Redland parser";
Chris@492 202 return false;
Chris@492 203 }
Chris@492 204
Chris@492 205 std::cerr << "About to parse \"" << uri.toStdString() << "\"" << std::endl;
Chris@492 206
Chris@492 207 Profiler p("SimpleSPARQLQuery: Parse URI into LIBRDF model");
Chris@492 208
Chris@492 209 if (librdf_parser_parse_into_model(parser, luri, NULL, model)) {
Chris@492 210
Chris@492 211 errorString = QString("Failed to parse RDF from URI \"%1\"")
Chris@492 212 .arg(uri);
Chris@492 213 librdf_free_parser(parser);
Chris@492 214 return false;
Chris@492 215
Chris@492 216 } else {
Chris@492 217
Chris@492 218 librdf_free_parser(parser);
Chris@492 219 return true;
Chris@492 220 }
Chris@492 221 }
Chris@492 222
Chris@492 223
Chris@439 224 class SimpleSPARQLQuery::Impl
Chris@439 225 {
Chris@439 226 public:
Chris@489 227 Impl(SimpleSPARQLQuery::QueryType, QString query);
Chris@439 228 ~Impl();
Chris@439 229
Chris@489 230 static bool addSourceToModel(QString sourceUri);
Chris@492 231 static void closeSingleSource(QString sourceUri);
Chris@489 232
Chris@439 233 void setProgressReporter(ProgressReporter *reporter) { m_reporter = reporter; }
Chris@439 234 bool wasCancelled() const { return m_cancelled; }
Chris@439 235
Chris@439 236 ResultList execute();
Chris@439 237
Chris@439 238 bool isOK() const;
Chris@439 239 QString getErrorString() const;
Chris@439 240
Chris@439 241 protected:
Chris@480 242 static QMutex m_mutex;
Chris@480 243
Chris@492 244 static WredlandWorldWrapper m_redland;
Chris@480 245
Chris@480 246 ResultList executeDirectParser();
Chris@480 247 ResultList executeDatastore();
Chris@492 248 ResultList executeFor(QString modelUri);
Chris@480 249
Chris@489 250 QueryType m_type;
Chris@439 251 QString m_query;
Chris@439 252 QString m_errorString;
Chris@439 253 ProgressReporter *m_reporter;
Chris@439 254 bool m_cancelled;
Chris@439 255 };
Chris@439 256
Chris@492 257 WredlandWorldWrapper SimpleSPARQLQuery::Impl::m_redland;
Chris@480 258
Chris@480 259 QMutex SimpleSPARQLQuery::Impl::m_mutex;
Chris@480 260
Chris@489 261 SimpleSPARQLQuery::SimpleSPARQLQuery(QueryType type, QString query) :
Chris@489 262 m_impl(new Impl(type, query))
Chris@480 263 {
Chris@480 264 }
Chris@439 265
Chris@439 266 SimpleSPARQLQuery::~SimpleSPARQLQuery()
Chris@439 267 {
Chris@439 268 delete m_impl;
Chris@439 269 }
Chris@439 270
Chris@439 271 void
Chris@439 272 SimpleSPARQLQuery::setProgressReporter(ProgressReporter *reporter)
Chris@439 273 {
Chris@439 274 m_impl->setProgressReporter(reporter);
Chris@439 275 }
Chris@439 276
Chris@439 277 bool
Chris@439 278 SimpleSPARQLQuery::wasCancelled() const
Chris@439 279 {
Chris@439 280 return m_impl->wasCancelled();
Chris@439 281 }
Chris@439 282
Chris@439 283 SimpleSPARQLQuery::ResultList
Chris@439 284 SimpleSPARQLQuery::execute()
Chris@439 285 {
Chris@439 286 return m_impl->execute();
Chris@439 287 }
Chris@439 288
Chris@439 289 bool
Chris@439 290 SimpleSPARQLQuery::isOK() const
Chris@439 291 {
Chris@439 292 return m_impl->isOK();
Chris@439 293 }
Chris@439 294
Chris@439 295 QString
Chris@439 296 SimpleSPARQLQuery::getErrorString() const
Chris@439 297 {
Chris@439 298 return m_impl->getErrorString();
Chris@439 299 }
Chris@439 300
Chris@489 301 bool
Chris@489 302 SimpleSPARQLQuery::addSourceToModel(QString sourceUri)
Chris@480 303 {
Chris@489 304 return SimpleSPARQLQuery::Impl::addSourceToModel(sourceUri);
Chris@480 305 }
Chris@480 306
Chris@492 307 void
Chris@492 308 SimpleSPARQLQuery::closeSingleSource(QString sourceUri)
Chris@492 309 {
Chris@492 310 SimpleSPARQLQuery::Impl::closeSingleSource(sourceUri);
Chris@492 311 }
Chris@492 312
Chris@489 313 SimpleSPARQLQuery::Impl::Impl(QueryType type, QString query) :
Chris@489 314 m_type(type),
Chris@439 315 m_query(query),
Chris@439 316 m_reporter(0),
Chris@439 317 m_cancelled(false)
Chris@439 318 {
Chris@439 319 }
Chris@439 320
Chris@439 321 SimpleSPARQLQuery::Impl::~Impl()
Chris@439 322 {
Chris@439 323 }
Chris@439 324
Chris@439 325 bool
Chris@439 326 SimpleSPARQLQuery::Impl::isOK() const
Chris@439 327 {
Chris@439 328 return (m_errorString == "");
Chris@439 329 }
Chris@439 330
Chris@439 331 QString
Chris@439 332 SimpleSPARQLQuery::Impl::getErrorString() const
Chris@439 333 {
Chris@439 334 return m_errorString;
Chris@439 335 }
Chris@439 336
Chris@439 337 SimpleSPARQLQuery::ResultList
Chris@439 338 SimpleSPARQLQuery::Impl::execute()
Chris@439 339 {
Chris@439 340 ResultList list;
Chris@439 341
Chris@490 342 QMutexLocker locker(&m_mutex);
Chris@480 343
Chris@492 344 if (!m_redland.isOK()) {
Chris@492 345 cerr << "ERROR: SimpleSPARQLQuery::execute: Failed to initialise Redland datastore" << endl;
Chris@492 346 return list;
Chris@440 347 }
Chris@480 348
Chris@489 349 if (m_type == QueryFromSingleSource) {
Chris@480 350 return executeDirectParser();
Chris@480 351 } else {
Chris@480 352 return executeDatastore();
Chris@480 353 }
Chris@492 354
Chris@492 355 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 356 if (m_errorString != "") {
Chris@492 357 std::cerr << "SimpleSPARQLQuery::execute: error returned: \""
Chris@492 358 << m_errorString.toStdString() << "\"" << std::endl;
Chris@492 359 }
Chris@492 360 #endif
Chris@480 361 }
Chris@480 362
Chris@480 363 SimpleSPARQLQuery::ResultList
Chris@480 364 SimpleSPARQLQuery::Impl::executeDirectParser()
Chris@480 365 {
Chris@492 366 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 367 std::cerr << "SimpleSPARQLQuery::executeDirectParser: Query is: \"" << m_query.toStdString() << "\"" << std::endl;
Chris@492 368 #endif
Chris@492 369
Chris@480 370 ResultList list;
Chris@480 371
Chris@480 372 Profiler profiler("SimpleSPARQLQuery::executeDirectParser");
Chris@480 373
Chris@492 374 static QRegExp fromRE("from\\s+<([^>]+)>", Qt::CaseInsensitive);
Chris@492 375 QString fromUri;
Chris@492 376
Chris@492 377 if (fromRE.indexIn(m_query) < 0) {
Chris@492 378 std::cerr << "SimpleSPARQLQuery::executeDirectParser: Query contains no FROM clause, nothing to parse from" << std::endl;
Chris@492 379 return list;
Chris@492 380 } else {
Chris@492 381 fromUri = fromRE.cap(1);
Chris@492 382 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 383 std::cerr << "SimpleSPARQLQuery::executeDirectParser: FROM URI is <"
Chris@492 384 << fromUri.toStdString() << ">" << std::endl;
Chris@440 385 #endif
Chris@439 386 }
Chris@439 387
Chris@492 388 return executeFor(fromUri);
Chris@439 389 }
Chris@440 390
Chris@480 391 SimpleSPARQLQuery::ResultList
Chris@480 392 SimpleSPARQLQuery::Impl::executeDatastore()
Chris@480 393 {
Chris@492 394 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 395 std::cerr << "SimpleSPARQLQuery::executeDatastore: Query is: \"" << m_query.toStdString() << "\"" << std::endl;
Chris@492 396 #endif
Chris@492 397
Chris@480 398 ResultList list;
Chris@489 399
Chris@480 400 Profiler profiler("SimpleSPARQLQuery::executeDatastore");
Chris@480 401
Chris@492 402 return executeFor("");
Chris@492 403 }
Chris@492 404
Chris@492 405 SimpleSPARQLQuery::ResultList
Chris@492 406 SimpleSPARQLQuery::Impl::executeFor(QString modelUri)
Chris@492 407 {
Chris@492 408 ResultList list;
Chris@492 409 librdf_query *query;
Chris@492 410
Chris@480 411 static std::map<QString, int> counter;
Chris@480 412 if (counter.find(m_query) == counter.end()) counter[m_query] = 1;
Chris@480 413 else ++counter[m_query];
Chris@480 414 std::cerr << "Counter for this query: " << counter[m_query] << std::endl;
Chris@492 415 std::cerr << "Base URI is: \"" << modelUri.toStdString() << "\"" << std::endl;
Chris@480 416
Chris@480 417 {
Chris@480 418 Profiler p("SimpleSPARQLQuery: Prepare LIBRDF query");
Chris@480 419 query = librdf_new_query
Chris@492 420 (m_redland.getWorld(), "sparql", NULL,
Chris@489 421 (const unsigned char *)m_query.toUtf8().data(), NULL);
Chris@480 422 }
Chris@480 423
Chris@480 424 if (!query) {
Chris@480 425 m_errorString = "Failed to construct query";
Chris@480 426 return list;
Chris@480 427 }
Chris@480 428
Chris@480 429 librdf_query_results *results;
Chris@480 430 {
Chris@480 431 Profiler p("SimpleSPARQLQuery: Execute LIBRDF query");
Chris@492 432 results = librdf_query_execute(query, m_redland.getModel(modelUri));
Chris@480 433 }
Chris@480 434
Chris@480 435 if (!results) {
Chris@480 436 cerr << "SimpleSPARQLQuery: LIBRDF query failed" << endl;
Chris@480 437 librdf_free_query(query);
Chris@480 438 return list;
Chris@480 439 }
Chris@480 440
Chris@480 441 if (!librdf_query_results_is_bindings(results)) {
Chris@480 442 cerr << "SimpleSPARQLQuery: LIBRDF query has wrong result type (not bindings)" << endl;
Chris@480 443 librdf_free_query_results(results);
Chris@480 444 librdf_free_query(query);
Chris@480 445 return list;
Chris@480 446 }
Chris@480 447
Chris@480 448 int resultCount = 0;
Chris@480 449 int resultTotal = librdf_query_results_get_count(results); // probably wrong
Chris@480 450 m_cancelled = false;
Chris@480 451
Chris@480 452 while (!librdf_query_results_finished(results)) {
Chris@480 453
Chris@480 454 int count = librdf_query_results_get_bindings_count(results);
Chris@480 455
Chris@480 456 KeyValueMap resultmap;
Chris@480 457
Chris@480 458 for (int i = 0; i < count; ++i) {
Chris@480 459
Chris@480 460 const char *name =
Chris@480 461 librdf_query_results_get_binding_name(results, i);
Chris@480 462
Chris@490 463 if (!name) {
Chris@490 464 std::cerr << "WARNING: Result " << i << " of query has no name" << std::endl;
Chris@490 465 continue;
Chris@490 466 }
Chris@490 467
Chris@480 468 librdf_node *node =
Chris@480 469 librdf_query_results_get_binding_value(results, i);
Chris@480 470
Chris@480 471 QString key = (const char *)name;
Chris@480 472
Chris@480 473 if (!node) {
Chris@492 474 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 475 std::cerr << i << ". " << key.toStdString() << " -> (nil)" << std::endl;
Chris@492 476 #endif
Chris@480 477 resultmap[key] = Value();
Chris@480 478 continue;
Chris@480 479 }
Chris@480 480
Chris@480 481 ValueType type = LiteralValue;
Chris@481 482 QString text;
Chris@481 483
Chris@481 484 if (librdf_node_is_resource(node)) {
Chris@481 485
Chris@481 486 type = URIValue;
Chris@481 487 librdf_uri *uri = librdf_node_get_uri(node);
Chris@490 488 const char *us = (const char *)librdf_uri_as_string(uri);
Chris@490 489
Chris@490 490 if (!us) {
Chris@490 491 std::cerr << "WARNING: Result " << i << " of query claims URI type, but has null URI" << std::endl;
Chris@490 492 } else {
Chris@490 493 text = us;
Chris@490 494 }
Chris@481 495
Chris@481 496 } else if (librdf_node_is_literal(node)) {
Chris@481 497
Chris@481 498 type = LiteralValue;
Chris@490 499
Chris@490 500 const char *lit = (const char *)librdf_node_get_literal_value(node);
Chris@490 501 if (!lit) {
Chris@490 502 std::cerr << "WARNING: Result " << i << " of query claims literal type, but has no literal" << std::endl;
Chris@490 503 } else {
Chris@490 504 text = lit;
Chris@490 505 }
Chris@481 506
Chris@481 507 } else if (librdf_node_is_blank(node)) {
Chris@481 508
Chris@481 509 type = BlankValue;
Chris@481 510
Chris@481 511 } else {
Chris@481 512
Chris@480 513 cerr << "SimpleSPARQLQuery: LIBRDF query returned unknown node type (not resource, literal, or blank)" << endl;
Chris@480 514 }
Chris@480 515
Chris@480 516 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@481 517 cerr << i << ". " << key.toStdString() << " -> " << text.toStdString() << " (type " << type << ")" << endl;
Chris@480 518 #endif
Chris@480 519
Chris@480 520 resultmap[key] = Value(type, text);
Chris@480 521
Chris@492 522 // librdf_free_node(node);
Chris@480 523 }
Chris@480 524
Chris@480 525 list.push_back(resultmap);
Chris@480 526
Chris@480 527 librdf_query_results_next(results);
Chris@480 528
Chris@480 529 resultCount++;
Chris@480 530
Chris@480 531 if (m_reporter) {
Chris@480 532 if (resultCount >= resultTotal) {
Chris@480 533 if (m_reporter->isDefinite()) m_reporter->setDefinite(false);
Chris@480 534 m_reporter->setProgress(resultCount);
Chris@480 535 } else {
Chris@480 536 m_reporter->setProgress((resultCount * 100) / resultTotal);
Chris@480 537 }
Chris@480 538
Chris@480 539 if (m_reporter->wasCancelled()) {
Chris@480 540 m_cancelled = true;
Chris@480 541 break;
Chris@480 542 }
Chris@480 543 }
Chris@480 544 }
Chris@480 545
Chris@480 546 librdf_free_query_results(results);
Chris@480 547 librdf_free_query(query);
Chris@480 548
Chris@481 549 #ifdef DEBUG_SIMPLE_SPARQL_QUERY
Chris@492 550 cerr << "SimpleSPARQLQuery::executeDatastore: All results retrieved (" << resultCount << " of them)" << endl;
Chris@481 551 #endif
Chris@480 552
Chris@480 553 return list;
Chris@489 554 }
Chris@489 555
Chris@489 556 bool
Chris@489 557 SimpleSPARQLQuery::Impl::addSourceToModel(QString sourceUri)
Chris@489 558 {
Chris@489 559 QString err;
Chris@489 560
Chris@490 561 QMutexLocker locker(&m_mutex);
Chris@489 562
Chris@492 563 if (!m_redland.isOK()) {
Chris@492 564 std::cerr << "SimpleSPARQLQuery::addSourceToModel: Failed to initialise Redland datastore" << std::endl;
Chris@492 565 return false;
Chris@489 566 }
Chris@489 567
Chris@492 568 if (!m_redland.loadUriIntoDefaultModel(sourceUri, err)) {
Chris@489 569 std::cerr << "SimpleSPARQLQuery::addSourceToModel: Failed to add source URI \"" << sourceUri.toStdString() << ": " << err.toStdString() << std::endl;
Chris@489 570 return false;
Chris@489 571 }
Chris@489 572 return true;
Chris@480 573 }
Chris@480 574
Chris@492 575 void
Chris@492 576 SimpleSPARQLQuery::Impl::closeSingleSource(QString sourceUri)
Chris@492 577 {
Chris@492 578 QMutexLocker locker(&m_mutex);
Chris@492 579
Chris@492 580 m_redland.freeModel(sourceUri);
Chris@492 581 }
Chris@492 582
Chris@440 583 SimpleSPARQLQuery::Value
Chris@489 584 SimpleSPARQLQuery::singleResultQuery(QueryType type,
Chris@480 585 QString query, QString binding)
Chris@440 586 {
Chris@489 587 SimpleSPARQLQuery q(type, query);
Chris@440 588 ResultList results = q.execute();
Chris@440 589 if (!q.isOK()) {
Chris@440 590 cerr << "SimpleSPARQLQuery::singleResultQuery: ERROR: "
Chris@440 591 << q.getErrorString().toStdString() << endl;
Chris@440 592 return Value();
Chris@440 593 }
Chris@440 594 if (results.empty()) {
Chris@440 595 return Value();
Chris@440 596 }
Chris@440 597 for (int i = 0; i < results.size(); ++i) {
Chris@440 598 if (results[i].find(binding) != results[i].end() &&
Chris@440 599 results[i][binding].type != NoValue) {
Chris@440 600 return results[i][binding];
Chris@440 601 }
Chris@440 602 }
Chris@440 603 return Value();
Chris@440 604 }
Chris@440 605
Chris@440 606
Chris@440 607