annotate rdf/SimpleSPARQLQuery.cpp @ 439:beb2948baa77

* Merge revisions 1041 to 1130 from sv-rdf-import branch
author Chris Cannam
date Thu, 18 Sep 2008 12:09:32 +0000
parents
children 5746c559af15
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@439 18
Chris@439 19 #include <rasqal.h>
Chris@439 20
Chris@439 21 #include <iostream>
Chris@439 22
Chris@439 23 using std::cerr;
Chris@439 24 using std::endl;
Chris@439 25
Chris@439 26 class SimpleSPARQLQuery::Impl
Chris@439 27 {
Chris@439 28 public:
Chris@439 29 Impl(QString query);
Chris@439 30 ~Impl();
Chris@439 31
Chris@439 32 void setProgressReporter(ProgressReporter *reporter) { m_reporter = reporter; }
Chris@439 33 bool wasCancelled() const { return m_cancelled; }
Chris@439 34
Chris@439 35 ResultList execute();
Chris@439 36
Chris@439 37 bool isOK() const;
Chris@439 38 QString getErrorString() const;
Chris@439 39
Chris@439 40 protected:
Chris@439 41 static void errorHandler(void *, raptor_locator *, const char *);
Chris@439 42
Chris@439 43 static bool m_initialised;
Chris@439 44
Chris@439 45 QString m_query;
Chris@439 46 QString m_errorString;
Chris@439 47 ProgressReporter *m_reporter;
Chris@439 48 bool m_cancelled;
Chris@439 49 };
Chris@439 50
Chris@439 51 SimpleSPARQLQuery::SimpleSPARQLQuery(QString query) :
Chris@439 52 m_impl(new Impl(query)) { }
Chris@439 53
Chris@439 54 SimpleSPARQLQuery::~SimpleSPARQLQuery()
Chris@439 55 {
Chris@439 56 delete m_impl;
Chris@439 57 }
Chris@439 58
Chris@439 59 void
Chris@439 60 SimpleSPARQLQuery::setProgressReporter(ProgressReporter *reporter)
Chris@439 61 {
Chris@439 62 m_impl->setProgressReporter(reporter);
Chris@439 63 }
Chris@439 64
Chris@439 65 bool
Chris@439 66 SimpleSPARQLQuery::wasCancelled() const
Chris@439 67 {
Chris@439 68 return m_impl->wasCancelled();
Chris@439 69 }
Chris@439 70
Chris@439 71 SimpleSPARQLQuery::ResultList
Chris@439 72 SimpleSPARQLQuery::execute()
Chris@439 73 {
Chris@439 74 return m_impl->execute();
Chris@439 75 }
Chris@439 76
Chris@439 77 bool
Chris@439 78 SimpleSPARQLQuery::isOK() const
Chris@439 79 {
Chris@439 80 return m_impl->isOK();
Chris@439 81 }
Chris@439 82
Chris@439 83 QString
Chris@439 84 SimpleSPARQLQuery::getErrorString() const
Chris@439 85 {
Chris@439 86 return m_impl->getErrorString();
Chris@439 87 }
Chris@439 88
Chris@439 89 bool
Chris@439 90 SimpleSPARQLQuery::Impl::m_initialised = false;
Chris@439 91
Chris@439 92 SimpleSPARQLQuery::Impl::Impl(QString query) :
Chris@439 93 m_query(query),
Chris@439 94 m_reporter(0),
Chris@439 95 m_cancelled(false)
Chris@439 96 {
Chris@439 97 //!!! fortunately this global stuff goes away in future rasqal versions
Chris@439 98 if (!m_initialised) {
Chris@439 99 rasqal_init();
Chris@439 100 }
Chris@439 101 }
Chris@439 102
Chris@439 103 SimpleSPARQLQuery::Impl::~Impl()
Chris@439 104 {
Chris@439 105 //!!! rasqal_finish();
Chris@439 106 }
Chris@439 107
Chris@439 108 bool
Chris@439 109 SimpleSPARQLQuery::Impl::isOK() const
Chris@439 110 {
Chris@439 111 return (m_errorString == "");
Chris@439 112 }
Chris@439 113
Chris@439 114 QString
Chris@439 115 SimpleSPARQLQuery::Impl::getErrorString() const
Chris@439 116 {
Chris@439 117 return m_errorString;
Chris@439 118 }
Chris@439 119
Chris@439 120 void
Chris@439 121 SimpleSPARQLQuery::Impl::errorHandler(void *data,
Chris@439 122 raptor_locator *locator,
Chris@439 123 const char *message)
Chris@439 124 {
Chris@439 125 SimpleSPARQLQuery::Impl *impl = (SimpleSPARQLQuery::Impl *)data;
Chris@439 126
Chris@439 127 // char buffer[256];
Chris@439 128 // raptor_format_locator(buffer, 255, locator);
Chris@439 129 // impl->m_errorString = QString("%1 - %2").arg(buffer).arg(message);
Chris@439 130
Chris@439 131 impl->m_errorString = message;
Chris@439 132
Chris@439 133 cerr << "SimpleSPARQLQuery: ERROR: " << impl->m_errorString.toStdString() << endl;
Chris@439 134 }
Chris@439 135
Chris@439 136 SimpleSPARQLQuery::ResultList
Chris@439 137 SimpleSPARQLQuery::Impl::execute()
Chris@439 138 {
Chris@439 139 ResultList list;
Chris@439 140
Chris@439 141 rasqal_query *query = rasqal_new_query("sparql", NULL);
Chris@439 142 if (!query) {
Chris@439 143 m_errorString = "Failed to construct query";
Chris@439 144 cerr << "SimpleSPARQLQuery: ERROR: " << m_errorString.toStdString() << endl;
Chris@439 145 return list;
Chris@439 146 }
Chris@439 147
Chris@439 148 rasqal_query_set_error_handler(query, this, errorHandler);
Chris@439 149 rasqal_query_set_fatal_error_handler(query, this, errorHandler);
Chris@439 150
Chris@439 151 if (rasqal_query_prepare
Chris@439 152 (query, (const unsigned char *)m_query.toUtf8().data(), NULL)) {
Chris@439 153 cerr << "SimpleSPARQLQuery: Failed to prepare query" << endl;
Chris@439 154 rasqal_free_query(query);
Chris@439 155 return list;
Chris@439 156 }
Chris@439 157
Chris@439 158 rasqal_query_results *results = rasqal_query_execute(query);
Chris@439 159
Chris@439 160 // cerr << "Query executed" << endl;
Chris@439 161
Chris@439 162 if (!results) {
Chris@439 163 cerr << "SimpleSPARQLQuery: RASQAL query failed" << endl;
Chris@439 164 rasqal_free_query(query);
Chris@439 165 return list;
Chris@439 166 }
Chris@439 167
Chris@439 168 if (!rasqal_query_results_is_bindings(results)) {
Chris@439 169 cerr << "SimpleSPARQLQuery: RASQAL query has wrong result type (not bindings)" << endl;
Chris@439 170 rasqal_free_query_results(results);
Chris@439 171 rasqal_free_query(query);
Chris@439 172 return list;
Chris@439 173 }
Chris@439 174
Chris@439 175 int resultCount = 0;
Chris@439 176 int resultTotal = rasqal_query_results_get_count(results); // probably wrong
Chris@439 177 m_cancelled = false;
Chris@439 178
Chris@439 179 while (!rasqal_query_results_finished(results)) {
Chris@439 180
Chris@439 181 int count = rasqal_query_results_get_bindings_count(results);
Chris@439 182
Chris@439 183 KeyValueMap resultmap;
Chris@439 184
Chris@439 185 for (int i = 0; i < count; ++i) {
Chris@439 186
Chris@439 187 const unsigned char *name =
Chris@439 188 rasqal_query_results_get_binding_name(results, i);
Chris@439 189
Chris@439 190 rasqal_literal *literal =
Chris@439 191 rasqal_query_results_get_binding_value(results, i);
Chris@439 192
Chris@439 193 QString key = (const char *)name;
Chris@439 194
Chris@439 195 if (!literal) {
Chris@439 196 resultmap[key] = Value();
Chris@439 197 continue;
Chris@439 198 }
Chris@439 199
Chris@439 200 ValueType type = LiteralValue;
Chris@439 201 if (literal->type == RASQAL_LITERAL_URI) type = URIValue;
Chris@439 202 else if (literal->type == RASQAL_LITERAL_BLANK) type = BlankValue;
Chris@439 203
Chris@439 204 QString text = (const char *)rasqal_literal_as_string(literal);
Chris@439 205
Chris@439 206 resultmap[key] = Value(type, text);
Chris@439 207 }
Chris@439 208
Chris@439 209 list.push_back(resultmap);
Chris@439 210
Chris@439 211 rasqal_query_results_next(results);
Chris@439 212
Chris@439 213 resultCount++;
Chris@439 214
Chris@439 215 if (m_reporter) {
Chris@439 216 if (resultCount >= resultTotal) {
Chris@439 217 if (m_reporter->isDefinite()) m_reporter->setDefinite(false);
Chris@439 218 m_reporter->setProgress(resultCount);
Chris@439 219 } else {
Chris@439 220 m_reporter->setProgress((resultCount * 100) / resultTotal);
Chris@439 221 }
Chris@439 222
Chris@439 223 if (m_reporter->wasCancelled()) {
Chris@439 224 m_cancelled = true;
Chris@439 225 break;
Chris@439 226 }
Chris@439 227 }
Chris@439 228 }
Chris@439 229
Chris@439 230 rasqal_free_query_results(results);
Chris@439 231 rasqal_free_query(query);
Chris@439 232
Chris@439 233 return list;
Chris@439 234 }
Chris@439 235