20 #include "personmanager_p.h"
25 #include <QStandardPaths>
28 #include <QDBusConnection>
29 #include <QDBusMessage>
34 Transaction(
const QSqlDatabase &db);
42 Transaction::Transaction(
const QSqlDatabase &db) :
49 void Transaction::cancel()
55 Transaction::~Transaction()
62 PersonManager::PersonManager(
const QString &databasePath, QObject *parent):
64 m_db(QSqlDatabase::addDatabase(QStringLiteral(
"QSQLITE")))
66 m_db.setDatabaseName(databasePath);
68 qWarning() <<
"Couldn't open the database at" << databasePath;
70 m_db.exec(QStringLiteral(
"CREATE TABLE IF NOT EXISTS persons (contactID VARCHAR UNIQUE NOT NULL, personID INT NOT NULL)"));
71 m_db.exec(QStringLiteral(
"CREATE INDEX IF NOT EXISTS contactIdIndex ON persons (contactId)"));
72 m_db.exec(QStringLiteral(
"CREATE INDEX IF NOT EXISTS personIdIndex ON persons (personId)"));
74 QDBusConnection::sessionBus().connect(QString(), QStringLiteral(
"/KPeople"), QStringLiteral(
"org.kde.KPeople"),
75 QStringLiteral(
"ContactAddedToPerson"),
this, SIGNAL(contactAddedToPerson(QString,QString)));
76 QDBusConnection::sessionBus().connect(QString(), QStringLiteral(
"/KPeople"), QStringLiteral(
"org.kde.KPeople"),
77 QStringLiteral(
"ContactRemovedFromPerson"),
this, SIGNAL(contactRemovedFromPerson(QString)));
80 PersonManager::~PersonManager()
85 QMultiHash< QString, QString > PersonManager::allPersons()
const
87 QMultiHash<QString , QString > contactMapping;
89 QSqlQuery query = m_db.exec(QStringLiteral(
"SELECT personID, contactID FROM persons"));
90 while (query.next()) {
91 const QString personUri = QLatin1String(
"kpeople://") + query.value(0).toString();
92 const QString contactID = query.value(1).toString();
93 contactMapping.insertMulti(personUri, contactID);
95 return contactMapping;
98 QStringList PersonManager::contactsForPersonUri(
const QString &personUri)
const
100 if (!personUri.startsWith(QLatin1String(
"kpeople://"))) {
101 return QStringList();
104 QStringList contactUris;
106 QSqlQuery query(m_db);
107 query.prepare(QStringLiteral(
"SELECT contactID FROM persons WHERE personId = ?"));
108 query.bindValue(0, personUri.mid(strlen(
"kpeople://")));
111 while (query.next()) {
112 contactUris << query.value(0).toString();
117 QString PersonManager::personUriForContact(
const QString &contactUri)
const
119 QSqlQuery query(m_db);
120 query.prepare(QStringLiteral(
"SELECT personId FROM persons WHERE contactId = ?"));
121 query.bindValue(0, contactUri);
124 return QLatin1String(
"kpeople://") + query.value(0).toString();
129 QString PersonManager::mergeContacts(
const QStringList &ids)
132 if (ids.size() < 2) {
136 QStringList metacontacts;
137 QStringList contacts;
141 QList<QDBusMessage> pendingMessages;
144 Q_FOREACH (
const QString &
id, ids) {
145 if (
id.startsWith(QLatin1String(
"kpeople://"))) {
155 QString personUriString;
156 if (metacontacts.count() == 0) {
159 QSqlQuery query = m_db.exec(QStringLiteral(
"SELECT MAX(personID) FROM persons"));
161 personUri = query.value(0).toInt();
165 personUriString = QLatin1String(
"kpeople://") + QString::number(personUri);
167 personUriString = metacontacts.first();
174 if (metacontacts.count() > 1) {
176 QStringList personContacts;
177 Q_FOREACH (
const QString &
id, metacontacts) {
178 if (
id != personUriString) {
179 personContacts << contactsForPersonUri(
id);
184 Q_FOREACH (
const QString &
id, personContacts) {
185 QSqlQuery updateQuery(m_db);
186 updateQuery.prepare(QStringLiteral(
"UPDATE persons SET personID = ? WHERE contactID = ?"));
187 updateQuery.bindValue(0, personUriString.mid(strlen(
"kpeople://")));
188 updateQuery.bindValue(1,
id);
189 if (!updateQuery.exec()) {
193 QDBusMessage message = QDBusMessage::createSignal(QLatin1String(
"/KPeople"),
194 QLatin1String(
"org.kde.KPeople"),
195 QLatin1String(
"ContactRemovedFromPerson"));
197 message.setArguments(QVariantList() <<
id);
198 pendingMessages << message;
200 message = QDBusMessage::createSignal(QLatin1String(
"/KPeople"),
201 QLatin1String(
"org.kde.KPeople"),
202 QLatin1String(
"ContactAddedToPerson"));
204 message.setArguments(QVariantList() <<
id << personUriString);
210 if (contacts.size() > 0) {
212 Q_FOREACH (
const QString &
id, contacts) {
213 QSqlQuery insertQuery(m_db);
214 insertQuery.prepare(QStringLiteral(
"INSERT INTO persons VALUES (?, ?)"));
215 insertQuery.bindValue(0,
id);
216 insertQuery.bindValue(1, personUriString.mid(strlen(
"kpeople://")));
217 if (!insertQuery.exec()) {
222 QDBusMessage message = QDBusMessage::createSignal(QLatin1String(
"/KPeople"),
223 QLatin1String(
"org.kde.KPeople"),
224 QLatin1String(
"ContactAddedToPerson"));
226 message.setArguments(QVariantList() <<
id << personUriString);
227 pendingMessages << message;
234 Q_FOREACH (
const QDBusMessage &message, pendingMessages) {
235 QDBusConnection::sessionBus().send(message);
239 personUriString.clear();
242 return personUriString;
245 bool PersonManager::unmergeContact(
const QString &
id)
248 if (
id.startsWith(QLatin1String(
"kpeople://"))) {
249 QSqlQuery query(m_db);
251 const QStringList contactUris = contactsForPersonUri(
id);
252 query.prepare(QStringLiteral(
"DELETE FROM persons WHERE personId = ?"));
253 query.bindValue(0,
id.mid(strlen(
"kpeople://")));
256 Q_FOREACH (
const QString &contactUri, contactUris) {
258 QDBusMessage message = QDBusMessage::createSignal(QLatin1String(
"/KPeople"),
259 QLatin1String(
"org.kde.KPeople"),
260 QLatin1String(
"ContactRemovedFromPerson"));
262 message.setArguments(QVariantList() << contactUri);
263 QDBusConnection::sessionBus().send(message);
266 QSqlQuery query(m_db);
267 query.prepare(QStringLiteral(
"DELETE FROM persons WHERE contactId = ?"));
268 query.bindValue(0,
id);
271 Q_EMIT contactRemovedFromPerson(
id);
278 PersonManager *PersonManager::instance(
const QString &databasePath)
280 static PersonManager *s_instance = 0;
282 QString path = databasePath;
283 if (path.isEmpty()) {
284 path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral(
"/kpeople/");
287 path += QLatin1String(
"persondb");
289 s_instance =
new PersonManager(path);