Chris@439: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@439: Chris@439: /* Chris@439: Sonic Visualiser Chris@439: An audio file viewer and annotation editor. Chris@439: Centre for Digital Music, Queen Mary, University of London. Chris@439: This file copyright 2008 QMUL. Chris@439: Chris@439: This program is free software; you can redistribute it and/or Chris@439: modify it under the terms of the GNU General Public License as Chris@439: published by the Free Software Foundation; either version 2 of the Chris@439: License, or (at your option) any later version. See the file Chris@439: COPYING included with this distribution for more information. Chris@439: */ Chris@439: Chris@439: #include "SimpleSPARQLQuery.h" Chris@439: #include "base/ProgressReporter.h" Chris@480: #include "base/Profiler.h" Chris@480: Chris@480: #include Chris@480: #include Chris@481: #include Chris@480: Chris@480: #include Chris@439: Chris@440: #ifdef USE_NEW_RASQAL_API Chris@440: #include Chris@440: #else Chris@439: #include Chris@440: #endif Chris@439: Chris@480: #ifdef HAVE_REDLAND Chris@480: #include Chris@480: #endif Chris@480: Chris@461: //#define DEBUG_SIMPLE_SPARQL_QUERY 1 Chris@461: Chris@439: #include Chris@439: Chris@439: using std::cerr; Chris@439: using std::endl; Chris@439: Chris@440: #ifdef USE_NEW_RASQAL_API Chris@440: class WrasqalWorldWrapper // wrong but wromantic, etc Chris@440: { Chris@440: public: Chris@481: WrasqalWorldWrapper() : Chris@481: m_world(0) Chris@481: { Chris@481: m_world = rasqal_new_world(); Chris@481: if (!m_world) { Chris@481: cerr << "SimpleSPARQLQuery: ERROR: Failed to create RASQAL world!" << endl; Chris@481: return; Chris@481: } Chris@481: /*!!! This appears to be new for 0.9.17? Chris@481: if (rasqal_world_open(m_world)) { Chris@481: cerr << "SimpleSPARQLQuery: ERROR: Failed to open RASQAL world!" << endl; Chris@481: return; Chris@481: } Chris@481: */ Chris@481: } Chris@481: ~WrasqalWorldWrapper() Chris@481: { Chris@481: rasqal_free_world(m_world); Chris@481: } Chris@440: Chris@480: rasqal_world *getWorld() { return m_world; } Chris@480: const rasqal_world *getWorld() const { return m_world; } Chris@440: Chris@440: private: Chris@440: rasqal_world *m_world; Chris@440: }; Chris@440: #endif Chris@440: Chris@480: #ifdef HAVE_REDLAND Chris@480: class WredlandWorldWrapper Chris@480: { Chris@480: public: Chris@480: WredlandWorldWrapper() : Chris@480: m_world(0), m_storage(0), m_model(0) Chris@480: { Chris@480: m_world = librdf_new_world(); Chris@481: if (!m_world) { Chris@481: cerr << "SimpleSPARQLQuery: ERROR: Failed to create LIBRDF world!" << endl; Chris@481: return; Chris@481: } Chris@480: librdf_world_open(m_world); Chris@481: m_storage = librdf_new_storage(m_world, "trees", NULL, NULL); Chris@480: if (!m_storage) { Chris@481: std::cerr << "SimpleSPARQLQuery: ERROR: Failed to initialise Redland trees datastore, falling back to memory store" << std::endl; Chris@480: m_storage = librdf_new_storage(m_world, NULL, NULL, NULL); Chris@480: if (!m_storage) { Chris@480: std::cerr << "SimpleSPARQLQuery: ERROR: Failed to initialise Redland memory datastore" << std::endl; Chris@480: return; Chris@480: } Chris@480: } Chris@480: m_model = librdf_new_model(m_world, m_storage, NULL); Chris@480: if (!m_model) { Chris@480: std::cerr << "SimpleSPARQLQuery: ERROR: Failed to initialise Redland data model" << std::endl; Chris@480: return; Chris@480: } Chris@480: } Chris@480: Chris@480: ~WredlandWorldWrapper() Chris@480: { Chris@480: while (!m_parsedUris.empty()) { Chris@480: librdf_free_uri(m_parsedUris.begin()->second); Chris@480: m_parsedUris.erase(m_parsedUris.begin()); Chris@480: } Chris@480: if (m_model) librdf_free_model(m_model); Chris@480: if (m_storage) librdf_free_storage(m_storage); Chris@480: if (m_world) librdf_free_world(m_world); Chris@480: } Chris@480: Chris@480: bool isOK() const { return (m_model != 0); } Chris@480: Chris@480: librdf_uri *getUri(QString uriString, QString &errorString) Chris@480: { Chris@480: QMutexLocker locker(&m_mutex); Chris@480: Chris@480: if (m_parsedUris.find(uriString) != m_parsedUris.end()) { Chris@480: return m_parsedUris[uriString]; Chris@480: } Chris@480: Chris@480: librdf_uri *uri = librdf_new_uri Chris@480: (m_world, (const unsigned char *)uriString.toUtf8().data()); Chris@480: if (!uri) { Chris@480: errorString = "Failed to construct librdf_uri!"; Chris@480: return 0; Chris@480: } Chris@480: Chris@480: librdf_parser *parser = librdf_new_parser(m_world, "guess", NULL, NULL); Chris@480: if (!parser) { Chris@480: errorString = "Failed to initialise Redland parser"; Chris@480: return 0; Chris@480: } Chris@480: Chris@480: std::cerr << "About to parse \"" << uriString.toStdString() << "\"" << std::endl; Chris@480: Chris@480: Profiler p("SimpleSPARQLQuery: Parse URI into LIBRDF model"); Chris@480: Chris@480: if (librdf_parser_parse_into_model(parser, uri, NULL, m_model)) { Chris@480: Chris@480: errorString = QString("Failed to parse RDF from URI \"%1\"") Chris@480: .arg(uriString); Chris@480: librdf_free_parser(parser); Chris@480: librdf_free_uri(uri); Chris@480: return 0; Chris@480: Chris@480: } else { Chris@480: Chris@480: librdf_free_parser(parser); Chris@480: m_parsedUris[uriString] = uri; Chris@480: return uri; Chris@480: } Chris@480: } Chris@480: Chris@480: librdf_world *getWorld() { return m_world; } Chris@480: const librdf_world *getWorld() const { return m_world; } Chris@480: Chris@480: librdf_model *getModel() { return m_model; } Chris@480: const librdf_model *getModel() const { return m_model; } Chris@480: Chris@480: private: Chris@480: librdf_world *m_world; Chris@480: librdf_storage *m_storage; Chris@480: librdf_model *m_model; Chris@480: Chris@480: QMutex m_mutex; Chris@480: std::map m_parsedUris; Chris@480: }; Chris@480: #endif Chris@480: Chris@439: class SimpleSPARQLQuery::Impl Chris@439: { Chris@439: public: Chris@480: Impl(QString fromUri, QString query); Chris@439: ~Impl(); Chris@439: Chris@439: void setProgressReporter(ProgressReporter *reporter) { m_reporter = reporter; } Chris@439: bool wasCancelled() const { return m_cancelled; } Chris@439: Chris@439: ResultList execute(); Chris@439: Chris@439: bool isOK() const; Chris@439: QString getErrorString() const; Chris@439: Chris@481: static void setBackEnd(SimpleSPARQLQuery::BackEndPreference p) { Chris@480: m_preference = p; Chris@480: } Chris@480: Chris@439: protected: Chris@439: static void errorHandler(void *, raptor_locator *, const char *); Chris@439: Chris@480: static QMutex m_mutex; Chris@480: Chris@440: #ifdef USE_NEW_RASQAL_API Chris@480: static WrasqalWorldWrapper *m_rasqal; Chris@440: #else Chris@480: static bool m_rasqalInitialised; Chris@440: #endif Chris@480: Chris@480: #ifdef HAVE_REDLAND Chris@480: static WredlandWorldWrapper *m_redland; Chris@480: #endif Chris@480: Chris@481: static SimpleSPARQLQuery::BackEndPreference m_preference; Chris@480: Chris@480: ResultList executeDirectParser(); Chris@480: ResultList executeDatastore(); Chris@480: Chris@480: QString m_fromUri; Chris@439: QString m_query; Chris@439: QString m_errorString; Chris@439: ProgressReporter *m_reporter; Chris@439: bool m_cancelled; Chris@439: }; Chris@439: Chris@440: #ifdef USE_NEW_RASQAL_API Chris@480: WrasqalWorldWrapper *SimpleSPARQLQuery::Impl::m_rasqal = 0; Chris@440: #else Chris@480: bool SimpleSPARQLQuery::Impl::m_rasqalInitialised = false; Chris@440: #endif Chris@440: Chris@480: #ifdef HAVE_REDLAND Chris@480: WredlandWorldWrapper *SimpleSPARQLQuery::Impl::m_redland = 0; Chris@480: #endif Chris@480: Chris@480: QMutex SimpleSPARQLQuery::Impl::m_mutex; Chris@480: Chris@481: SimpleSPARQLQuery::BackEndPreference Chris@481: SimpleSPARQLQuery::Impl::m_preference = SimpleSPARQLQuery::AutoSelectBackEnd; Chris@480: Chris@480: SimpleSPARQLQuery::SimpleSPARQLQuery(QString fromUri, QString query) : Chris@480: m_impl(new Impl(fromUri, query)) Chris@480: { Chris@480: } Chris@439: Chris@439: SimpleSPARQLQuery::~SimpleSPARQLQuery() Chris@439: { Chris@439: delete m_impl; Chris@439: } Chris@439: Chris@439: void Chris@439: SimpleSPARQLQuery::setProgressReporter(ProgressReporter *reporter) Chris@439: { Chris@439: m_impl->setProgressReporter(reporter); Chris@439: } Chris@439: Chris@439: bool Chris@439: SimpleSPARQLQuery::wasCancelled() const Chris@439: { Chris@439: return m_impl->wasCancelled(); Chris@439: } Chris@439: Chris@439: SimpleSPARQLQuery::ResultList Chris@439: SimpleSPARQLQuery::execute() Chris@439: { Chris@439: return m_impl->execute(); Chris@439: } Chris@439: Chris@439: bool Chris@439: SimpleSPARQLQuery::isOK() const Chris@439: { Chris@439: return m_impl->isOK(); Chris@439: } Chris@439: Chris@439: QString Chris@439: SimpleSPARQLQuery::getErrorString() const Chris@439: { Chris@439: return m_impl->getErrorString(); Chris@439: } Chris@439: Chris@480: void Chris@481: SimpleSPARQLQuery::setBackEnd(BackEndPreference p) Chris@480: { Chris@481: SimpleSPARQLQuery::Impl::setBackEnd(p); Chris@480: } Chris@480: Chris@480: SimpleSPARQLQuery::Impl::Impl(QString fromUri, QString query) : Chris@480: m_fromUri(fromUri), Chris@439: m_query(query), Chris@439: m_reporter(0), Chris@439: m_cancelled(false) Chris@439: { Chris@461: #ifdef DEBUG_SIMPLE_SPARQL_QUERY Chris@461: std::cerr << "SimpleSPARQLQuery::Impl: Query is: \"" << query.toStdString() << "\"" << std::endl; Chris@461: #endif Chris@439: } Chris@439: Chris@439: SimpleSPARQLQuery::Impl::~Impl() Chris@439: { Chris@439: } Chris@439: Chris@439: bool Chris@439: SimpleSPARQLQuery::Impl::isOK() const Chris@439: { Chris@439: return (m_errorString == ""); Chris@439: } Chris@439: Chris@439: QString Chris@439: SimpleSPARQLQuery::Impl::getErrorString() const Chris@439: { Chris@439: return m_errorString; Chris@439: } Chris@439: Chris@439: void Chris@439: SimpleSPARQLQuery::Impl::errorHandler(void *data, Chris@439: raptor_locator *locator, Chris@439: const char *message) Chris@439: { Chris@439: SimpleSPARQLQuery::Impl *impl = (SimpleSPARQLQuery::Impl *)data; Chris@439: Chris@481: char buffer[256]; Chris@481: raptor_format_locator(buffer, 255, locator); Chris@481: QString loc(buffer); Chris@481: if (loc != "") { Chris@481: impl->m_errorString = QString("%1 - %2").arg(loc).arg(message); Chris@481: } else { Chris@481: impl->m_errorString = message; Chris@481: } Chris@439: Chris@439: cerr << "SimpleSPARQLQuery: ERROR: " << impl->m_errorString.toStdString() << endl; Chris@439: } Chris@439: Chris@439: SimpleSPARQLQuery::ResultList Chris@439: SimpleSPARQLQuery::Impl::execute() Chris@439: { Chris@439: ResultList list; Chris@439: Chris@481: BackEndPreference preference; Chris@480: Chris@480: m_mutex.lock(); Chris@480: Chris@481: if (m_preference == AutoSelectBackEnd) { Chris@481: #ifdef HAVE_REDLAND Chris@481: // cerr << "librdf version: " << librdf_version_major << "." << librdf_version_minor << "." << librdf_version_release << endl; Chris@481: if (librdf_version_major > 1 || Chris@481: (librdf_version_major == 1 && Chris@481: (librdf_version_minor > 0 || Chris@481: (librdf_version_minor == 0 && Chris@481: librdf_version_release > 7)))) { Chris@481: cerr << "SimpleSPARQLQuery: Auto-selecting LIBRDF back-end for tree-based storage" << endl; Chris@481: m_preference = DatastoreBackEnd; Chris@481: } Chris@481: #endif Chris@481: if (m_preference == AutoSelectBackEnd) { Chris@481: cerr << "SimpleSPARQLQuery: Auto-selecting RASQAL back-end" << endl; Chris@481: m_preference = DirectParserBackEnd; Chris@481: } Chris@481: } Chris@481: Chris@481: if (m_preference == DatastoreBackEnd) { Chris@480: #ifdef HAVE_REDLAND Chris@480: if (!m_redland) { Chris@480: m_redland = new WredlandWorldWrapper(); Chris@480: if (!m_redland->isOK()) { Chris@480: cerr << "WARNING: SimpleSPARQLQuery::execute: Failed to initialise Redland datastore, falling back to direct parser implementation" << endl; Chris@480: delete m_redland; Chris@481: m_preference = DirectParserBackEnd; Chris@480: } Chris@480: } Chris@480: #else Chris@480: cerr << "WARNING: SimpleSPARQLQuery::execute: Datastore implementation preference indicated, but no datastore compiled in; using direct parser" << endl; Chris@481: m_preference = DirectParserBackEnd; Chris@480: #endif Chris@480: } Chris@480: Chris@481: if (m_preference == DirectParserBackEnd) { Chris@440: #ifdef USE_NEW_RASQAL_API Chris@480: if (!m_rasqal) m_rasqal = new WrasqalWorldWrapper(); Chris@440: #else Chris@480: if (!m_rasqalInitialised) { Chris@480: rasqal_init(); Chris@480: m_rasqalInitialised = true; Chris@480: } Chris@480: #endif Chris@440: } Chris@480: Chris@480: preference = m_preference; Chris@480: m_mutex.unlock(); Chris@480: Chris@481: if (preference == SimpleSPARQLQuery::DirectParserBackEnd) { Chris@480: return executeDirectParser(); Chris@480: } else { Chris@480: return executeDatastore(); Chris@480: } Chris@480: } Chris@480: Chris@480: SimpleSPARQLQuery::ResultList Chris@480: SimpleSPARQLQuery::Impl::executeDirectParser() Chris@480: { Chris@480: ResultList list; Chris@480: Chris@480: Profiler profiler("SimpleSPARQLQuery::executeDirectParser"); Chris@480: Chris@480: #ifdef USE_NEW_RASQAL_API Chris@480: rasqal_query *query = rasqal_new_query(m_rasqal->getWorld(), "sparql", NULL); Chris@480: #else Chris@439: rasqal_query *query = rasqal_new_query("sparql", NULL); Chris@440: #endif Chris@439: if (!query) { Chris@439: m_errorString = "Failed to construct query"; Chris@439: cerr << "SimpleSPARQLQuery: ERROR: " << m_errorString.toStdString() << endl; Chris@439: return list; Chris@439: } Chris@439: Chris@439: rasqal_query_set_error_handler(query, this, errorHandler); Chris@439: rasqal_query_set_fatal_error_handler(query, this, errorHandler); Chris@439: Chris@480: { Chris@480: Profiler p("SimpleSPARQLQuery: Prepare RASQAL query"); Chris@480: Chris@480: if (rasqal_query_prepare Chris@480: (query, (const unsigned char *)m_query.toUtf8().data(), NULL)) { Chris@480: cerr << "SimpleSPARQLQuery: Failed to prepare query" << endl; Chris@480: rasqal_free_query(query); Chris@480: return list; Chris@480: } Chris@439: } Chris@439: Chris@480: rasqal_query_results *results; Chris@480: Chris@480: { Chris@480: Profiler p("SimpleSPARQLQuery: Execute RASQAL query"); Chris@480: results = rasqal_query_execute(query); Chris@480: } Chris@439: Chris@439: // cerr << "Query executed" << endl; Chris@439: Chris@439: if (!results) { Chris@439: cerr << "SimpleSPARQLQuery: RASQAL query failed" << endl; Chris@439: rasqal_free_query(query); Chris@439: return list; Chris@439: } Chris@439: Chris@439: if (!rasqal_query_results_is_bindings(results)) { Chris@439: cerr << "SimpleSPARQLQuery: RASQAL query has wrong result type (not bindings)" << endl; Chris@439: rasqal_free_query_results(results); Chris@439: rasqal_free_query(query); Chris@439: return list; Chris@439: } Chris@439: Chris@439: int resultCount = 0; Chris@439: int resultTotal = rasqal_query_results_get_count(results); // probably wrong Chris@439: m_cancelled = false; Chris@439: Chris@439: while (!rasqal_query_results_finished(results)) { Chris@439: Chris@439: int count = rasqal_query_results_get_bindings_count(results); Chris@439: Chris@439: KeyValueMap resultmap; Chris@439: Chris@439: for (int i = 0; i < count; ++i) { Chris@439: Chris@439: const unsigned char *name = Chris@439: rasqal_query_results_get_binding_name(results, i); Chris@439: Chris@439: rasqal_literal *literal = Chris@439: rasqal_query_results_get_binding_value(results, i); Chris@439: Chris@439: QString key = (const char *)name; Chris@439: Chris@439: if (!literal) { Chris@439: resultmap[key] = Value(); Chris@439: continue; Chris@439: } Chris@439: Chris@439: ValueType type = LiteralValue; Chris@439: if (literal->type == RASQAL_LITERAL_URI) type = URIValue; Chris@439: else if (literal->type == RASQAL_LITERAL_BLANK) type = BlankValue; Chris@439: Chris@439: QString text = (const char *)rasqal_literal_as_string(literal); Chris@439: Chris@461: #ifdef DEBUG_SIMPLE_SPARQL_QUERY Chris@449: std::cerr << i << ". " << key.toStdString() << " -> " << text.toStdString() << " (type " << type << ")" << std::endl; Chris@461: #endif Chris@449: Chris@439: resultmap[key] = Value(type, text); Chris@439: } Chris@439: Chris@439: list.push_back(resultmap); Chris@439: Chris@439: rasqal_query_results_next(results); Chris@439: Chris@439: resultCount++; Chris@439: Chris@439: if (m_reporter) { Chris@439: if (resultCount >= resultTotal) { Chris@439: if (m_reporter->isDefinite()) m_reporter->setDefinite(false); Chris@439: m_reporter->setProgress(resultCount); Chris@439: } else { Chris@439: m_reporter->setProgress((resultCount * 100) / resultTotal); Chris@439: } Chris@439: Chris@439: if (m_reporter->wasCancelled()) { Chris@439: m_cancelled = true; Chris@439: break; Chris@439: } Chris@439: } Chris@439: } Chris@439: Chris@439: rasqal_free_query_results(results); Chris@439: rasqal_free_query(query); Chris@439: Chris@439: return list; Chris@439: } Chris@440: Chris@480: SimpleSPARQLQuery::ResultList Chris@480: SimpleSPARQLQuery::Impl::executeDatastore() Chris@480: { Chris@480: ResultList list; Chris@480: #ifndef HAVE_REDLAND Chris@480: // This should have been caught by execute() Chris@480: cerr << "SimpleSPARQLQuery: INTERNAL ERROR: Datastore not compiled in" << endl; Chris@480: return list; Chris@480: #else Chris@480: Profiler profiler("SimpleSPARQLQuery::executeDatastore"); Chris@480: Chris@480: librdf_uri *uri = m_redland->getUri(m_fromUri, m_errorString); Chris@480: if (!uri) return list; Chris@480: Chris@481: #ifdef DEBUG_SIMPLE_SPARQL_QUERY Chris@480: std::cerr << "SimpleSPARQLQuery: Query is: \"" << m_query.toStdString() << "\"" << std::endl; Chris@481: #endif Chris@481: /*!!! Chris@480: static std::map counter; Chris@480: if (counter.find(m_query) == counter.end()) counter[m_query] = 1; Chris@480: else ++counter[m_query]; Chris@480: std::cerr << "Counter for this query: " << counter[m_query] << std::endl; Chris@481: std::cerr << "Base URI is: \"" << m_fromUri.toStdString() << "\"" << std::endl; Chris@481: */ Chris@480: Chris@480: librdf_query *query; Chris@480: Chris@480: { Chris@480: Profiler p("SimpleSPARQLQuery: Prepare LIBRDF query"); Chris@480: query = librdf_new_query Chris@480: (m_redland->getWorld(), "sparql", NULL, Chris@480: (const unsigned char *)m_query.toUtf8().data(), uri); Chris@480: } Chris@480: Chris@480: if (!query) { Chris@480: m_errorString = "Failed to construct query"; Chris@480: return list; Chris@480: } Chris@480: Chris@480: librdf_query_results *results; Chris@480: { Chris@480: Profiler p("SimpleSPARQLQuery: Execute LIBRDF query"); Chris@480: results = librdf_query_execute(query, m_redland->getModel()); Chris@480: } Chris@480: Chris@480: if (!results) { Chris@480: cerr << "SimpleSPARQLQuery: LIBRDF query failed" << endl; Chris@480: librdf_free_query(query); Chris@480: return list; Chris@480: } Chris@480: Chris@480: if (!librdf_query_results_is_bindings(results)) { Chris@480: cerr << "SimpleSPARQLQuery: LIBRDF query has wrong result type (not bindings)" << endl; Chris@480: librdf_free_query_results(results); Chris@480: librdf_free_query(query); Chris@480: return list; Chris@480: } Chris@480: Chris@480: int resultCount = 0; Chris@480: int resultTotal = librdf_query_results_get_count(results); // probably wrong Chris@480: m_cancelled = false; Chris@480: Chris@480: while (!librdf_query_results_finished(results)) { Chris@480: Chris@480: int count = librdf_query_results_get_bindings_count(results); Chris@480: Chris@480: KeyValueMap resultmap; Chris@480: Chris@480: for (int i = 0; i < count; ++i) { Chris@480: Chris@480: const char *name = Chris@480: librdf_query_results_get_binding_name(results, i); Chris@480: Chris@480: librdf_node *node = Chris@480: librdf_query_results_get_binding_value(results, i); Chris@480: Chris@480: QString key = (const char *)name; Chris@480: Chris@480: if (!node) { Chris@480: resultmap[key] = Value(); Chris@480: continue; Chris@480: } Chris@480: Chris@480: ValueType type = LiteralValue; Chris@481: QString text; Chris@481: Chris@481: if (librdf_node_is_resource(node)) { Chris@481: Chris@481: type = URIValue; Chris@481: librdf_uri *uri = librdf_node_get_uri(node); Chris@481: text = (const char *)librdf_uri_as_string(uri); Chris@481: Chris@481: } else if (librdf_node_is_literal(node)) { Chris@481: Chris@481: type = LiteralValue; Chris@481: text = (const char *)librdf_node_get_literal_value(node); Chris@481: Chris@481: } else if (librdf_node_is_blank(node)) { Chris@481: Chris@481: type = BlankValue; Chris@481: Chris@481: } else { Chris@481: Chris@480: cerr << "SimpleSPARQLQuery: LIBRDF query returned unknown node type (not resource, literal, or blank)" << endl; Chris@480: } Chris@480: Chris@480: #ifdef DEBUG_SIMPLE_SPARQL_QUERY Chris@481: cerr << i << ". " << key.toStdString() << " -> " << text.toStdString() << " (type " << type << ")" << endl; Chris@480: #endif Chris@480: Chris@480: resultmap[key] = Value(type, text); Chris@480: Chris@480: librdf_free_node(node); Chris@480: } Chris@480: Chris@480: list.push_back(resultmap); Chris@480: Chris@480: librdf_query_results_next(results); Chris@480: Chris@480: resultCount++; Chris@480: Chris@480: if (m_reporter) { Chris@480: if (resultCount >= resultTotal) { Chris@480: if (m_reporter->isDefinite()) m_reporter->setDefinite(false); Chris@480: m_reporter->setProgress(resultCount); Chris@480: } else { Chris@480: m_reporter->setProgress((resultCount * 100) / resultTotal); Chris@480: } Chris@480: Chris@480: if (m_reporter->wasCancelled()) { Chris@480: m_cancelled = true; Chris@480: break; Chris@480: } Chris@480: } Chris@480: } Chris@480: Chris@480: librdf_free_query_results(results); Chris@480: librdf_free_query(query); Chris@480: Chris@481: #ifdef DEBUG_SIMPLE_SPARQL_QUERY Chris@481: cerr << "All results retrieved (" << resultCount << " of them)" << endl; Chris@481: #endif Chris@480: Chris@480: return list; Chris@480: #endif Chris@480: } Chris@480: Chris@440: SimpleSPARQLQuery::Value Chris@480: SimpleSPARQLQuery::singleResultQuery(QString fromUri, Chris@480: QString query, QString binding) Chris@440: { Chris@480: SimpleSPARQLQuery q(fromUri, query); Chris@440: ResultList results = q.execute(); Chris@440: if (!q.isOK()) { Chris@440: cerr << "SimpleSPARQLQuery::singleResultQuery: ERROR: " Chris@440: << q.getErrorString().toStdString() << endl; Chris@440: return Value(); Chris@440: } Chris@440: if (results.empty()) { Chris@440: return Value(); Chris@440: } Chris@440: for (int i = 0; i < results.size(); ++i) { Chris@440: if (results[i].find(binding) != results[i].end() && Chris@440: results[i][binding].type != NoValue) { Chris@440: return results[i][binding]; Chris@440: } Chris@440: } Chris@440: return Value(); Chris@440: } Chris@440: Chris@440: Chris@440: