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: #include Chris@480: Chris@490: #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@489: bool isOK() const { return (m_world != 0); } Chris@489: 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: 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: 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@490: // 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: Chris@439: class SimpleSPARQLQuery::Impl Chris@439: { Chris@439: public: Chris@489: Impl(SimpleSPARQLQuery::QueryType, QString query); Chris@439: ~Impl(); Chris@439: Chris@489: static bool addSourceToModel(QString sourceUri); Chris@489: 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@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: static WredlandWorldWrapper *m_redland; Chris@480: Chris@480: ResultList executeDirectParser(); Chris@480: ResultList executeDatastore(); Chris@480: Chris@489: QueryType m_type; 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: WredlandWorldWrapper *SimpleSPARQLQuery::Impl::m_redland = 0; Chris@480: Chris@480: QMutex SimpleSPARQLQuery::Impl::m_mutex; Chris@480: Chris@489: SimpleSPARQLQuery::SimpleSPARQLQuery(QueryType type, QString query) : Chris@489: m_impl(new Impl(type, 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@489: bool Chris@489: SimpleSPARQLQuery::addSourceToModel(QString sourceUri) Chris@480: { Chris@489: return SimpleSPARQLQuery::Impl::addSourceToModel(sourceUri); Chris@480: } Chris@480: Chris@489: SimpleSPARQLQuery::Impl::Impl(QueryType type, QString query) : Chris@489: m_type(type), 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@490: QMutexLocker locker(&m_mutex); Chris@480: Chris@489: if (m_type == QueryFromModel) { Chris@489: if (!m_redland) { Chris@489: // There can be no results, because no sources have been Chris@489: // added to the model yet (m_redland is only created when Chris@489: // addSourceToModel is called) Chris@489: cerr << "SimpleSPARQLQuery::execute: NOTE: No sources have been added to data model yet, so no results are possible" << endl; Chris@489: return list; Chris@481: } Chris@481: } Chris@481: Chris@489: if (m_type == QueryFromSingleSource) { Chris@489: #ifdef USE_NEW_RASQAL_API Chris@489: if (!m_rasqal) { Chris@489: m_rasqal = new WrasqalWorldWrapper(); Chris@489: if (!m_rasqal->isOK()) { Chris@489: cerr << "ERROR: SimpleSPARQLQuery::execute: Failed to initialise Rasqal query engine" << endl; Chris@489: delete m_rasqal; Chris@489: m_rasqal = 0; Chris@489: return list; Chris@480: } Chris@480: } Chris@480: #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@489: if (m_type == QueryFromSingleSource) { 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@490: if (!name) { Chris@490: std::cerr << "WARNING: Result " << i << " of query has no name" << std::endl; Chris@490: continue; Chris@490: } Chris@490: 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@490: if (literal->type == RASQAL_LITERAL_BLANK) type = BlankValue; Chris@490: else if (literal->type == RASQAL_LITERAL_URI) type = URIValue; Chris@439: Chris@490: QString text; Chris@490: const char *lit = (const char *)rasqal_literal_as_string(literal); Chris@490: if (!lit) { Chris@490: std::cerr << "WARNING: Result " << i << " of query has null value" << std::endl; Chris@490: } else { Chris@490: text = lit; Chris@490: } 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@489: Chris@480: Profiler profiler("SimpleSPARQLQuery::executeDatastore"); Chris@480: 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@489: (const unsigned char *)m_query.toUtf8().data(), NULL); 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@490: if (!name) { Chris@490: std::cerr << "WARNING: Result " << i << " of query has no name" << std::endl; Chris@490: continue; Chris@490: } Chris@490: 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@490: const char *us = (const char *)librdf_uri_as_string(uri); Chris@490: Chris@490: if (!us) { Chris@490: std::cerr << "WARNING: Result " << i << " of query claims URI type, but has null URI" << std::endl; Chris@490: } else { Chris@490: text = us; Chris@490: } Chris@481: Chris@481: } else if (librdf_node_is_literal(node)) { Chris@481: Chris@481: type = LiteralValue; Chris@490: Chris@490: const char *lit = (const char *)librdf_node_get_literal_value(node); Chris@490: if (!lit) { Chris@490: std::cerr << "WARNING: Result " << i << " of query claims literal type, but has no literal" << std::endl; Chris@490: } else { Chris@490: text = lit; Chris@490: } 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@489: } Chris@489: Chris@489: bool Chris@489: SimpleSPARQLQuery::Impl::addSourceToModel(QString sourceUri) Chris@489: { Chris@489: QString err; Chris@489: Chris@490: QMutexLocker locker(&m_mutex); Chris@489: Chris@489: if (!m_redland) { Chris@489: m_redland = new WredlandWorldWrapper(); Chris@489: if (!m_redland->isOK()) { Chris@489: cerr << "ERROR: SimpleSPARQLQuery::addSourceToModel: Failed to initialise Redland datastore" << endl; Chris@489: delete m_redland; Chris@489: m_redland = 0; Chris@489: return false; Chris@489: } Chris@489: } Chris@489: Chris@489: librdf_uri *uri = m_redland->getUri(sourceUri, err); Chris@489: Chris@489: if (!uri) { Chris@489: std::cerr << "SimpleSPARQLQuery::addSourceToModel: Failed to add source URI \"" << sourceUri.toStdString() << ": " << err.toStdString() << std::endl; Chris@489: return false; Chris@489: } Chris@489: return true; Chris@480: } Chris@480: Chris@440: SimpleSPARQLQuery::Value Chris@489: SimpleSPARQLQuery::singleResultQuery(QueryType type, Chris@480: QString query, QString binding) Chris@440: { Chris@489: SimpleSPARQLQuery q(type, 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: