1/*
2 * This file is part of Soprano Project.
3 *
4 * Copyright (C) 2008 Sebastian Trueg <trueg@kde.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#ifndef _SOPRANO_ASYNC_MODEL_H_
23#define _SOPRANO_ASYNC_MODEL_H_
24
25#include "filtermodel.h"
26#include "asyncresult.h" // backwards comp when AsyncResult was defined in this header
27
28#include "soprano_export.h"
29
30
31namespace Soprano {
32
33 class Statement;
34 class StatementIterator;
35 class Node;
36 class NodeIterator;
37 class QueryResultIterator;
38
39 namespace Util {
40
41 class AsyncModelPrivate;
42
43 /**
44 * \class AsyncModel asyncmodel.h Soprano/Server/AsyncModel
45 *
46 * \brief Filter model that allows to perform operations
47 * asyncroneously.
48 *
49 * AsyncModel has two modes: AsyncModel::SingleThreaded and AsyncModel::MultiThreaded.
50 * The main purpose of the AsyncModel::SingleThreaded mode is to protect a
51 * Model against deadlocks in a single threaded situation.
52 *
53 * AsyncModel::MultiThreaded mode provides real asyncroneous execution of
54 * Model commands.
55 *
56 * Usage:
57 * \code
58 * AsyncResult* result = model->listStatementsAsync( s );
59 * connect( result, SIGNAL(resultReady(AsyncResult*)),
60 * this, SLOT(slotResultReady(AsyncResult*)) );
61 * \endcode
62 *
63 * \author Sebastian Trueg <trueg@kde.org>
64 *
65 * \since 2.1
66 */
67 class SOPRANO_EXPORT AsyncModel : public FilterModel
68 {
69 Q_OBJECT
70
71 public:
72 /**
73 * Create a new Model.
74 *
75 * \param parent The parent model to forward the operations to.
76 */
77 AsyncModel( Model* parent = 0 );
78
79 /**
80 * Destructor.
81 */
82 ~AsyncModel();
83
84 /**
85 * The mode of the model, single vs. multi threaded execution.
86 *
87 * \since 2.2
88 */
89 enum AsyncModelMode {
90 /**
91 * The model uses a single thread. Thus, commands are executed in the
92 * same thread but no two commands will ever block each other.
93 * This is the default mode for historical reasons.
94 */
95 SingleThreaded,
96
97 /**
98 * The model uses multiple threads through QThreadPool.
99 * Commands are executed in parallel.
100 * Be aware that the parent model needs to be thread-safe.
101 */
102 MultiThreaded
103 };
104
105 /**
106 * Set the mode to be used. For historical reasons the default mode is
107 * SingleThreaded.
108 *
109 * \sa mode
110 *
111 * \since 2.2
112 */
113 void setMode( AsyncModelMode mode );
114
115 /**
116 * The mode used by this model.
117 *
118 * \sa setMode
119 *
120 * \since 2.2
121 */
122 AsyncModelMode mode() const;
123
124 /**
125 * Asyncroneously add the Statement to the Model.
126 *
127 * \param statement The Statement to add.
128 *
129 * \sa addStatement
130 *
131 * \return an AsyncResult with result type Error::ErrorCode
132 * object which will signal when the result is ready.
133 */
134 AsyncResult* addStatementAsync( const Statement& statement );
135
136 /**
137 * \overload
138 *
139 * \since 2.2
140 */
141 AsyncResult* addStatementAsync( const Node& subject, const Node& predicate, const Node& object, const Node& context = Node() );
142
143 /**
144 * \overload
145 *
146 * \since 2.2
147 */
148 AsyncResult* addStatementsAsync( const QList<Statement>& statements );
149
150 /**
151 * Asyncroneously remove one statement. For removing statements
152 * with wildward matching see removeAllStatementsAsync().
153 *
154 * \param statement The statement that should be removed.
155 * This has to be a valid statement.
156 *
157 * \sa removeStatement
158 *
159 * \return an AsyncResult with result type Error::ErrorCode
160 * object which will signal when the result is ready.
161 */
162 AsyncResult* removeStatementAsync( const Statement& statement );
163
164 /**
165 * \overload
166 *
167 * \since 2.2
168 */
169 AsyncResult* removeStatementAsync( const Node& subject, const Node& predicate, const Node& object, const Node& context = Node() );
170
171 /**
172 * \overload
173 *
174 * \since 2.2
175 */
176 AsyncResult* removeStatementsAsync( const QList<Statement>& statements );
177
178 /**
179 * Asyncroneously remove all statements that match the partial statement.
180 * For removing one specific statement see removeStatement().
181 *
182 * \param statement A possible partially defined statement that serves as
183 * a filter for all statements that should be removed.
184 *
185 * \sa removeAllStatements
186 *
187 * \return an AsyncResult with result type Error::ErrorCode
188 * object which will signal when the result is ready.
189 */
190 AsyncResult* removeAllStatementsAsync( const Statement& statement );
191
192 /**
193 * \overload
194 *
195 * \since 2.2
196 */
197 AsyncResult* removeAllStatementsAsync( const Node& subject, const Node& predicate, const Node& object, const Node& context = Node() );
198
199 /**
200 * Asyncroneously check if the Model does contain any Statement.
201 *
202 * \sa isEmpty
203 *
204 * \return an AsyncResult with result type bool
205 * object which will signal when the result is ready.
206 */
207 AsyncResult* isEmptyAsync() const;
208
209 /**
210 * Asyncroneously determine the number of statements stored in this Model.
211 *
212 * \sa statementCount
213 *
214 * \return an AsyncResult with result type int
215 * object which will signal when the result is ready.
216 */
217 AsyncResult* statementCountAsync() const;
218
219 /**
220 * Asyncroneously return an iterator over Model Statements that "partial"
221 * match the input Statement.
222 *
223 * \param statement The partial Statement to match.
224 *
225 * \sa listStatements
226 *
227 * \return an AsyncResult with result type StatementIterator
228 * object which will signal when the result is ready.
229 */
230 AsyncResult* listStatementsAsync( const Statement& statement ) const;
231
232 /**
233 * \overload
234 *
235 * \since 2.2
236 */
237 AsyncResult* listStatementsAsync( const Node& subject, const Node& predicate, const Node& object, const Node& context = Node() ) const;
238
239 /**
240 * \overload
241 *
242 * Lists all statements in the Model asyncroneously.
243 *
244 * \since 2.2
245 */
246 AsyncResult* listStatementsAsync() const;
247
248 /**
249 * Asyncroneously list all contexts in the model, i.e. all named graphs.
250 *
251 * \sa listContexts
252 *
253 * \return an AsyncResult with result type NodeIterator
254 * object which will signal when the result is ready.
255 */
256 AsyncResult* listContextsAsync() const;
257
258 /**
259 * Asyncroneously execute the given query over the Model.
260 *
261 * This is a const read-only method. As such Model implementations should not
262 * support SPARQL extensions such as INSERT or UPDATE through this method.
263 * A future version of %Soprano will provide an additional API for queries
264 * that change the Model.
265 *
266 * \param query The query to evaluate.
267 * \param language The %query language used to encode \p query.
268 * \param userQueryLanguage If \p language equals Query::QueryLanguageUser
269 * userQueryLanguage defines the language to use.
270 *
271 * \sa executeQuery
272 *
273 * \return an AsyncResult with result type QueryResultIterator
274 * object which will signal when the result is ready.
275 */
276 AsyncResult* executeQueryAsync( const QString& query,
277 Query::QueryLanguage language,
278 const QString& userQueryLanguage = QString() ) const;
279
280 /**
281 * AsyncResult check if the model contains a statements.
282 *
283 * \param statement The statement in question. This has to be a valid statement,
284 * i.e. subject, predicate, and object need to be defined. If the context node
285 * is empty the default graph is searched.
286 *
287 * \sa containsStatement
288 *
289 * \return an AsyncResult with result type bool
290 * object which will signal when the result is ready.
291 */
292 AsyncResult* containsStatementAsync( const Statement& statement ) const;
293
294 /**
295 * \overload
296 *
297 * \since 2.2
298 */
299 AsyncResult* containsStatementAsync( const Node& subject, const Node& predicate, const Node& object, const Node& context = Node() ) const;
300
301 /**
302 * Asyncroneously check if the model contains certain statements.
303 *
304 * \param statement A partially defined statement that serves as
305 * a pattern.
306 *
307 * \sa containsAnyStatement
308 *
309 * \return an AsyncResult with result type bool
310 * object which will signal when the result is ready.
311 */
312 AsyncResult* containsAnyStatementAsync( const Statement& statement ) const;
313
314 /**
315 * \overload
316 *
317 * \since 2.2
318 */
319 AsyncResult* containsAnyStatementAsync( const Node& subject, const Node& predicate, const Node& object, const Node& context = Node() ) const;
320
321 /**
322 * Asyncroneously create a new blank node with a unique identifier.
323 *
324 * \sa createBlankNode
325 *
326 * \return an AsyncResult with result type Node
327 * object which will signal when the result is ready.
328 */
329 AsyncResult* createBlankNodeAsync();
330
331 /**
332 * \reimplemented
333 *
334 * The call is directly delivered to the parent model. However, the iterator is counted so that interweaving
335 * asyncroneous and non-asyncroneous calls does not result in unwanted behaviour.
336 *
337 * \since 2.4
338 */
339 StatementIterator listStatements( const Statement& partial ) const;
340
341 /**
342 * \reimplemented
343 *
344 * The call is directly delivered to the parent model. However, the iterator is counted so that interweaving
345 * asyncroneous and non-asyncroneous calls does not result in unwanted behaviour.
346 *
347 * \since 2.4
348 */
349 NodeIterator listContexts() const;
350
351 /**
352 * \reimplemented
353 *
354 * The call is directly delivered to the parent model. However, the iterator is counted so that interweaving
355 * asyncroneous and non-asyncroneous calls does not result in unwanted behaviour.
356 *
357 * \since 2.4
358 */
359 QueryResultIterator executeQuery( const QString& query, Query::QueryLanguage language, const QString& userQueryLanguage = QString() ) const;
360
361 using FilterModel::addStatement;
362 using FilterModel::removeStatement;
363 using FilterModel::removeAllStatements;
364 using FilterModel::listStatements;
365 using FilterModel::containsStatement;
366 using FilterModel::containsAnyStatement;
367
368 private:
369 AsyncModelPrivate* const d;
370
371 Q_PRIVATE_SLOT( d, void _s_executeNextCommand() )
372 };
373 }
374}
375
376#endif
377