Mercurial > hg > svcore
comparison 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 |
comparison
equal
deleted
inserted
replaced
438:32c399d06374 | 439:beb2948baa77 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2008 QMUL. | |
8 | |
9 This program is free software; you can redistribute it and/or | |
10 modify it under the terms of the GNU General Public License as | |
11 published by the Free Software Foundation; either version 2 of the | |
12 License, or (at your option) any later version. See the file | |
13 COPYING included with this distribution for more information. | |
14 */ | |
15 | |
16 #include "SimpleSPARQLQuery.h" | |
17 #include "base/ProgressReporter.h" | |
18 | |
19 #include <rasqal.h> | |
20 | |
21 #include <iostream> | |
22 | |
23 using std::cerr; | |
24 using std::endl; | |
25 | |
26 class SimpleSPARQLQuery::Impl | |
27 { | |
28 public: | |
29 Impl(QString query); | |
30 ~Impl(); | |
31 | |
32 void setProgressReporter(ProgressReporter *reporter) { m_reporter = reporter; } | |
33 bool wasCancelled() const { return m_cancelled; } | |
34 | |
35 ResultList execute(); | |
36 | |
37 bool isOK() const; | |
38 QString getErrorString() const; | |
39 | |
40 protected: | |
41 static void errorHandler(void *, raptor_locator *, const char *); | |
42 | |
43 static bool m_initialised; | |
44 | |
45 QString m_query; | |
46 QString m_errorString; | |
47 ProgressReporter *m_reporter; | |
48 bool m_cancelled; | |
49 }; | |
50 | |
51 SimpleSPARQLQuery::SimpleSPARQLQuery(QString query) : | |
52 m_impl(new Impl(query)) { } | |
53 | |
54 SimpleSPARQLQuery::~SimpleSPARQLQuery() | |
55 { | |
56 delete m_impl; | |
57 } | |
58 | |
59 void | |
60 SimpleSPARQLQuery::setProgressReporter(ProgressReporter *reporter) | |
61 { | |
62 m_impl->setProgressReporter(reporter); | |
63 } | |
64 | |
65 bool | |
66 SimpleSPARQLQuery::wasCancelled() const | |
67 { | |
68 return m_impl->wasCancelled(); | |
69 } | |
70 | |
71 SimpleSPARQLQuery::ResultList | |
72 SimpleSPARQLQuery::execute() | |
73 { | |
74 return m_impl->execute(); | |
75 } | |
76 | |
77 bool | |
78 SimpleSPARQLQuery::isOK() const | |
79 { | |
80 return m_impl->isOK(); | |
81 } | |
82 | |
83 QString | |
84 SimpleSPARQLQuery::getErrorString() const | |
85 { | |
86 return m_impl->getErrorString(); | |
87 } | |
88 | |
89 bool | |
90 SimpleSPARQLQuery::Impl::m_initialised = false; | |
91 | |
92 SimpleSPARQLQuery::Impl::Impl(QString query) : | |
93 m_query(query), | |
94 m_reporter(0), | |
95 m_cancelled(false) | |
96 { | |
97 //!!! fortunately this global stuff goes away in future rasqal versions | |
98 if (!m_initialised) { | |
99 rasqal_init(); | |
100 } | |
101 } | |
102 | |
103 SimpleSPARQLQuery::Impl::~Impl() | |
104 { | |
105 //!!! rasqal_finish(); | |
106 } | |
107 | |
108 bool | |
109 SimpleSPARQLQuery::Impl::isOK() const | |
110 { | |
111 return (m_errorString == ""); | |
112 } | |
113 | |
114 QString | |
115 SimpleSPARQLQuery::Impl::getErrorString() const | |
116 { | |
117 return m_errorString; | |
118 } | |
119 | |
120 void | |
121 SimpleSPARQLQuery::Impl::errorHandler(void *data, | |
122 raptor_locator *locator, | |
123 const char *message) | |
124 { | |
125 SimpleSPARQLQuery::Impl *impl = (SimpleSPARQLQuery::Impl *)data; | |
126 | |
127 // char buffer[256]; | |
128 // raptor_format_locator(buffer, 255, locator); | |
129 // impl->m_errorString = QString("%1 - %2").arg(buffer).arg(message); | |
130 | |
131 impl->m_errorString = message; | |
132 | |
133 cerr << "SimpleSPARQLQuery: ERROR: " << impl->m_errorString.toStdString() << endl; | |
134 } | |
135 | |
136 SimpleSPARQLQuery::ResultList | |
137 SimpleSPARQLQuery::Impl::execute() | |
138 { | |
139 ResultList list; | |
140 | |
141 rasqal_query *query = rasqal_new_query("sparql", NULL); | |
142 if (!query) { | |
143 m_errorString = "Failed to construct query"; | |
144 cerr << "SimpleSPARQLQuery: ERROR: " << m_errorString.toStdString() << endl; | |
145 return list; | |
146 } | |
147 | |
148 rasqal_query_set_error_handler(query, this, errorHandler); | |
149 rasqal_query_set_fatal_error_handler(query, this, errorHandler); | |
150 | |
151 if (rasqal_query_prepare | |
152 (query, (const unsigned char *)m_query.toUtf8().data(), NULL)) { | |
153 cerr << "SimpleSPARQLQuery: Failed to prepare query" << endl; | |
154 rasqal_free_query(query); | |
155 return list; | |
156 } | |
157 | |
158 rasqal_query_results *results = rasqal_query_execute(query); | |
159 | |
160 // cerr << "Query executed" << endl; | |
161 | |
162 if (!results) { | |
163 cerr << "SimpleSPARQLQuery: RASQAL query failed" << endl; | |
164 rasqal_free_query(query); | |
165 return list; | |
166 } | |
167 | |
168 if (!rasqal_query_results_is_bindings(results)) { | |
169 cerr << "SimpleSPARQLQuery: RASQAL query has wrong result type (not bindings)" << endl; | |
170 rasqal_free_query_results(results); | |
171 rasqal_free_query(query); | |
172 return list; | |
173 } | |
174 | |
175 int resultCount = 0; | |
176 int resultTotal = rasqal_query_results_get_count(results); // probably wrong | |
177 m_cancelled = false; | |
178 | |
179 while (!rasqal_query_results_finished(results)) { | |
180 | |
181 int count = rasqal_query_results_get_bindings_count(results); | |
182 | |
183 KeyValueMap resultmap; | |
184 | |
185 for (int i = 0; i < count; ++i) { | |
186 | |
187 const unsigned char *name = | |
188 rasqal_query_results_get_binding_name(results, i); | |
189 | |
190 rasqal_literal *literal = | |
191 rasqal_query_results_get_binding_value(results, i); | |
192 | |
193 QString key = (const char *)name; | |
194 | |
195 if (!literal) { | |
196 resultmap[key] = Value(); | |
197 continue; | |
198 } | |
199 | |
200 ValueType type = LiteralValue; | |
201 if (literal->type == RASQAL_LITERAL_URI) type = URIValue; | |
202 else if (literal->type == RASQAL_LITERAL_BLANK) type = BlankValue; | |
203 | |
204 QString text = (const char *)rasqal_literal_as_string(literal); | |
205 | |
206 resultmap[key] = Value(type, text); | |
207 } | |
208 | |
209 list.push_back(resultmap); | |
210 | |
211 rasqal_query_results_next(results); | |
212 | |
213 resultCount++; | |
214 | |
215 if (m_reporter) { | |
216 if (resultCount >= resultTotal) { | |
217 if (m_reporter->isDefinite()) m_reporter->setDefinite(false); | |
218 m_reporter->setProgress(resultCount); | |
219 } else { | |
220 m_reporter->setProgress((resultCount * 100) / resultTotal); | |
221 } | |
222 | |
223 if (m_reporter->wasCancelled()) { | |
224 m_cancelled = true; | |
225 break; | |
226 } | |
227 } | |
228 } | |
229 | |
230 rasqal_free_query_results(results); | |
231 rasqal_free_query(query); | |
232 | |
233 return list; | |
234 } | |
235 |