Changes: Use QSparqlQueryOptions in runQuery
[qtcontacts-tracker:hasselmms-qtcontacts-tracker.git] / src / engine / relationshipremoverequest.cpp
1 /** This file is part of QtContacts tracker storage plugin
2  **
3  ** Copyright (c) 2009-2011 Nokia Corporation and/or its subsidiary(-ies).
4  **
5  ** Contact:  Nokia Corporation (info@qt.nokia.com)
6  **
7  ** GNU Lesser General Public License Usage
8  ** This file may be used under the terms of the GNU Lesser General Public License
9  ** version 2.1 as published by the Free Software Foundation and appearing in the
10  ** file LICENSE.LGPL included in the packaging of this file.  Please review the
11  ** following information to ensure the GNU Lesser General Public License version
12  ** 2.1 requirements will be met:
13  ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
14  **
15  ** In addition, as a special exception, Nokia gives you certain additional rights.
16  ** These rights are described in the Nokia Qt LGPL Exception version 1.1, included
17  ** in the file LGPL_EXCEPTION.txt in this package.
18  **
19  ** Other Usage
20  ** Alternatively, this file may be used in accordance with the terms and
21  ** conditions contained in a signed written agreement between you and Nokia.
22  **/
23
24 #include "relationshipremoverequest.h"
25
26 #include <engine/engine.h>
27
28 #include <QtSparql>
29
30 ///////////////////////////////////////////////////////////////////////////////////////////////////
31
32 QTrackerRelationshipRemoveRequest::QTrackerRelationshipRemoveRequest(QContactAbstractRequest *request,
33                                                                      QContactTrackerEngine *engine,
34                                                                      QObject *parent)
35     : QTrackerBaseRequest<QContactRelationshipRemoveRequest>(engine, parent)
36     , m_relationships(staticCast(request)->relationships())
37 {
38 }
39
40 QTrackerRelationshipRemoveRequest::~QTrackerRelationshipRemoveRequest()
41 {
42 }
43
44 QString
45 QTrackerRelationshipRemoveRequest::buildQuery() const
46 {
47     static const QString queryTemplate = QLatin1String
48             ("DELETE {\n"
49              "  ?c nco:belongsToGroup ?g\n"
50              "} WHERE {\n"
51              "  ?g a nco:Contact FILTER(tracker:id(?g) = %1).\n"
52              "  ?c a nco:Contact FILTER(tracker:id(?c) = %2).\n"
53              "}\n");
54
55     QStringList queries;
56
57     foreach (const QContactRelationship &relationship, m_relationships) {
58         const QContactLocalId groupContactLocalId = relationship.first().localId();
59         const QContactLocalId memberContactLocalId = relationship.second().localId();
60
61         queries.append(queryTemplate.arg(QString::number(groupContactLocalId),
62                                          QString::number(memberContactLocalId)));
63     }
64
65     return queries.join(QLatin1String("\n\n"));
66 }
67
68 bool
69 QTrackerRelationshipRemoveRequest::validateRelationships()
70 {
71     const QList<QContactRelationship> &relationships = m_relationships;
72
73     for(int i = 0; i < relationships.count(); ++i) {
74         const QString relationshipType = relationships[i].relationshipType();
75
76         if (QContactRelationship::HasMember != relationshipType) {
77             m_errorMap.insert(i, QContactManager::NotSupportedError);
78         }
79     }
80
81     // assuming m_errorMap was empty before invokation
82     return m_errorMap.isEmpty();
83 }
84
85 void
86 QTrackerRelationshipRemoveRequest::run()
87 {
88     setCancelable(false);
89
90     if (canceled()) {
91         emitResultLater();
92         return;
93     }
94
95     // We explicitly don't check for contact existance (DoesNotExistError error) because:
96     //
97     // 1) Checking for contact existance costs time.
98     // 2) More importantly checking for contact existance would be entirely racy.
99     //    Therefore such a feature would be entirely random and useless.
100     //
101     // If some customer explicitly asks for that feature we can spend time on how to implement
102     // an atomic contact existance check. Still this check would have to be explicitely requested
103     // per contact manager parameter for first reason.
104
105     if (validateRelationships()) {
106         delete runQuery(QSparqlQuery(buildQuery(), QSparqlQuery::DeleteStatement), SyncQueryOptions);
107     } else {
108         setLastError(QContactManager::NotSupportedError);
109     }
110
111     emitResultLater();
112 }
113
114 void
115 QTrackerRelationshipRemoveRequest::emitResult(QContactManager::Error error)
116 {
117     engine()->updateRelationshipRemoveRequest(staticCast(engine()->request(this).data()),
118                                               error, m_errorMap, QContactAbstractRequest::FinishedState);
119 }