Changes: Use QSparqlQueryOptions in runQuery
[qtcontacts-tracker:hasselmms-qtcontacts-tracker.git] / src / engine / relationshipsaverequest.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 "relationshipsaverequest.h"
25
26 #include <engine/engine.h>
27
28 #include <QtSparql>
29
30 ///////////////////////////////////////////////////////////////////////////////////////////////////
31
32 QTrackerRelationshipSaveRequest::QTrackerRelationshipSaveRequest(QContactAbstractRequest *request,
33                                                                  QContactTrackerEngine *engine,
34                                                                  QObject *parent)
35     : QTrackerBaseRequest<QContactRelationshipSaveRequest>(engine, parent)
36     , m_relationships(staticCast(request)->relationships())
37 {
38 }
39
40 void
41 QTrackerRelationshipSaveRequest::run()
42 {
43     setCancelable(false);
44
45     if (canceled()) {
46         emitResultLater();
47         return;
48     }
49
50     if (m_relationships.isEmpty()) {
51         setLastError(QContactManager::BadArgumentError);
52         emitResultLater();
53         return;
54     }
55
56     static const QString sparqlTemplate = QLatin1String
57             ("INSERT {\n"
58              "  GRAPH <%3> {\n"
59              "    ?member nco:belongsToGroup ?group\n"
60              "  }\n"
61              "}\n"
62              "WHERE {\n"
63              "  ?member a nco:Contact . ?group a nco:Contact .\n"
64              "  FILTER(%1=tracker:id(?member) && %2=tracker:id(?group))\n"
65              "}\n");
66
67     QString queryString;
68
69     static const int digitsPerUInt = log(UINT_MAX) / log(10);
70     queryString.reserve((sparqlTemplate.length() + 2 * digitsPerUInt) * m_relationships.length());
71
72     // TODO: support saving of foreign relationships
73     for (int i = 0; i < m_relationships.length(); ++i) {
74         const QContactRelationship relationship = m_relationships.at(i);
75
76         if (relationship.relationshipType() != QContactRelationship::HasMember) {
77             qctWarn(QString::fromLatin1("Only HasMember relationships supported, got %1").
78                     arg(relationship.relationshipType()));
79             m_errorMap.insert(i, QContactManager::NotSupportedError);
80             continue;
81         }
82
83         if (relationship.first().managerUri() != engine()->managerUri() ||
84             relationship.second().managerUri() != engine()->managerUri()) {
85             qctWarn(QString::fromLatin1("Foreign contact/group currently not supported: group %1, contact %2").
86                     arg(relationship.first().managerUri(), relationship.second().managerUri()));
87             m_errorMap.insert(i, QContactManager::InvalidRelationshipError);
88             continue;
89         }
90
91         m_savedRelations += relationship;
92
93         queryString += sparqlTemplate.arg(QString::number(relationship.second().localId()),
94                                           QString::number(relationship.first().localId()),
95                                           engine()->graphIri());
96     }
97
98     if (not m_savedRelations.isEmpty()) {
99         delete runQuery(QSparqlQuery(queryString, QSparqlQuery::InsertStatement), SyncQueryOptions);
100     } else if (not m_errorMap.empty()) {
101         setLastError(QContactManager::UnspecifiedError);
102     }
103
104     emitResultLater();
105 }
106
107 void QTrackerRelationshipSaveRequest::emitResult(QContactManager::Error error)
108
109 {
110     engine()->updateRelationshipSaveRequest(staticCast(engine()->request(this).data()),
111                                             m_savedRelations, error, m_errorMap,
112                                             QContactAbstractRequest::FinishedState);
113 }