Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Linus Jahn
kaidan
Commits
2e2ae1d5
Commit
2e2ae1d5
authored
Jun 12, 2017
by
Linus Jahn
Committed by
GitHub
Jun 12, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add database versioning and conversion (#110)
Closes #95.
parent
630b184f
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
322 additions
and
119 deletions
+322
-119
src/CMakeLists.txt
src/CMakeLists.txt
+1
-0
src/Database.cpp
src/Database.cpp
+209
-0
src/Database.h
src/Database.h
+49
-0
src/Kaidan.cpp
src/Kaidan.cpp
+14
-12
src/Kaidan.h
src/Kaidan.h
+3
-1
src/MessageController.cpp
src/MessageController.cpp
+3
-4
src/MessageController.h
src/MessageController.h
+3
-2
src/MessageModel.cpp
src/MessageModel.cpp
+4
-32
src/MessageModel.h
src/MessageModel.h
+2
-1
src/RosterController.cpp
src/RosterController.cpp
+3
-2
src/RosterController.h
src/RosterController.h
+1
-1
src/RosterModel.cpp
src/RosterModel.cpp
+25
-37
src/RosterModel.h
src/RosterModel.h
+5
-1
src/main.cpp
src/main.cpp
+0
-26
No files found.
src/CMakeLists.txt
View file @
2e2ae1d5
...
...
@@ -4,6 +4,7 @@ set(CURDIR ${CMAKE_CURRENT_LIST_DIR})
set
(
KAIDAN_SOURCES
${
CURDIR
}
/main.cpp
${
CURDIR
}
/Kaidan.cpp
${
CURDIR
}
/Database.cpp
${
CURDIR
}
/RosterController.cpp
${
CURDIR
}
/RosterModel.cpp
${
CURDIR
}
/MessageController.cpp
...
...
src/Database.cpp
0 → 100644
View file @
2e2ae1d5
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2017 LNJ <git@lnj.li>
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Database.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QStandardPaths>
#include <QString>
#include <QStringList>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
static
const
unsigned
int
DATABASE_LATEST_VERSION
=
2
;
static
const
char
*
DATABASE_TABLE_INFO
=
"dbinfo"
;
static
const
char
*
DATABASE_TABLE_MESSAGES
=
"Messages"
;
static
const
char
*
DATABASE_TABLE_ROSTER
=
"Roster"
;
Database
::
Database
(
QObject
*
parent
)
:
QObject
(
parent
)
{
version
=
-
1
;
database
=
QSqlDatabase
::
addDatabase
(
"QSQLITE"
,
"kaidan_default_db"
);
if
(
!
database
.
isValid
())
{
qFatal
(
"Cannot add database: %s"
,
qPrintable
(
database
.
lastError
().
text
()));
}
}
Database
::~
Database
()
{
database
.
close
();
}
QSqlDatabase
*
Database
::
getDatabase
()
{
return
&
database
;
}
void
Database
::
openDatabase
()
{
const
QDir
writeDir
=
QStandardPaths
::
writableLocation
(
QStandardPaths
::
AppDataLocation
);
if
(
!
writeDir
.
mkpath
(
"."
))
{
qFatal
(
"Failed to create writable directory at %s"
,
qPrintable
(
writeDir
.
absolutePath
()));
}
// Ensure that we have a writable location on all devices.
const
QString
fileName
=
writeDir
.
absoluteFilePath
(
"messages.sqlite3"
);
// open() will create the SQLite database if it doesn't exist.
database
.
setDatabaseName
(
fileName
);
if
(
!
database
.
open
())
{
qFatal
(
"Cannot open database: %s"
,
qPrintable
(
database
.
lastError
().
text
()));
QFile
::
remove
(
fileName
);
}
loadDatabaseInfo
();
}
void
Database
::
loadDatabaseInfo
()
{
QStringList
tables
=
database
.
tables
();
if
(
!
tables
.
contains
(
DATABASE_TABLE_INFO
))
{
if
(
tables
.
contains
(
DATABASE_TABLE_MESSAGES
)
&&
tables
.
contains
(
DATABASE_TABLE_ROSTER
))
{
// old Kaidan v0.1/v0.2 table
version
=
1
;
}
else
{
version
=
0
;
}
}
QSqlQuery
query
(
database
);
query
.
prepare
(
"SELECT version FROM dbinfo"
);
if
(
!
query
.
exec
())
{
qWarning
(
"Cannot query database info: %s"
,
qPrintable
(
database
.
lastError
().
text
()));
}
QSqlRecord
record
=
query
.
record
();
int
versionCol
=
record
.
indexOf
(
"version"
);
while
(
query
.
next
())
{
version
=
query
.
value
(
versionCol
).
toInt
();
}
}
bool
Database
::
needToConvert
()
{
if
(
version
<
DATABASE_LATEST_VERSION
)
{
return
true
;
}
return
false
;
}
void
Database
::
convertDatabase
()
{
qDebug
()
<<
"[Database] Converting database to latest version from verion"
<<
version
;
switch
(
version
)
{
case
0
:
createNewDatabase
();
break
;
case
1
:
convertDatabaseToV2
();
// only break on last convertion step, to not enter default (!)
break
;
default:
createNewDatabase
();
}
QSqlQuery
query
(
database
);
query
.
prepare
(
QString
(
"UPDATE dbinfo SET version = %1"
).
arg
(
DATABASE_LATEST_VERSION
));
if
(
!
query
.
exec
())
{
qDebug
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
database
.
commit
();
version
=
DATABASE_LATEST_VERSION
;
}
void
Database
::
createNewDatabase
()
{
QSqlQuery
query
(
database
);
//
// DB info
//
createDbInfoTable
();
//
// Roster
//
if
(
!
query
.
exec
(
"CREATE TABLE IF NOT EXISTS 'Roster' ("
"'jid' TEXT NOT NULL,"
"'name' TEXT NOT NULL,"
"'lastExchanged' TEXT NOT NULL,"
"'unreadMessages' INTEGER,"
"'lastMessage' TEXT,"
"'lastOnline' TEXT,"
// < UNUSED v
"'activity' TEXT,"
"'status' TEXT,"
"'mood' TEXT"
// < UNUSED ^
")"
))
{
qFatal
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
//
// Messages
//
if
(
!
query
.
exec
(
"CREATE TABLE IF NOT EXISTS 'Messages' ("
"'author' TEXT NOT NULL,"
"'author_resource' TEXT,"
"'recipient' TEXT NOT NULL,"
"'recipient_resource' TEXT,"
"'timestamp' TEXT NOT NULL,"
"'message' TEXT NOT NULL,"
"'id' TEXT NOT NULL,"
"'isSent' BOOL,"
// is sent to server
"'isDelivered' BOOL,"
// message has arrived at other client
"FOREIGN KEY('author') REFERENCES Roster ('jid'),"
"FOREIGN KEY('recipient') REFERENCES Roster ('jid')"
")"
))
{
qFatal
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
}
void
Database
::
createDbInfoTable
()
{
QSqlQuery
query
(
database
);
query
.
prepare
(
"CREATE TABLE IF NOT EXISTS 'dbinfo' (version INTEGER NOT NULL)"
);
if
(
!
query
.
exec
())
{
qFatal
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
query
.
prepare
(
QString
(
"INSERT INTO 'dbinfo' (version) VALUES (%1)"
)
.
arg
(
DATABASE_LATEST_VERSION
));
if
(
!
query
.
exec
())
{
qFatal
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
}
void
Database
::
convertDatabaseToV2
()
{
// create a new dbinfo table
createDbInfoTable
();
}
src/Database.h
0 → 100644
View file @
2e2ae1d5
/*
* Kaidan - A user-friendly XMPP client for every device!
*
* Copyright (C) 2017 LNJ <git@lnj.li>
*
* Kaidan is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Kaidan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kaidan. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DATABASE_H
#define DATABASE_H
#include <QObject>
#include <QSqlDatabase>
class
Database
:
public
QObject
{
Q_OBJECT
public:
Database
(
QObject
*
parent
=
0
);
~
Database
();
QSqlDatabase
*
getDatabase
();
bool
needToConvert
();
void
convertDatabase
();
void
openDatabase
();
private:
void
loadDatabaseInfo
();
void
createDbInfoTable
();
void
createNewDatabase
();
void
convertDatabaseToV2
();
QSqlDatabase
database
;
int
version
;
};
#endif // DATABASE_H
src/Kaidan.cpp
View file @
2e2ae1d5
...
...
@@ -43,10 +43,21 @@
#include "VCardController.h"
#include "ServiceDiscoveryManager.h"
Kaidan
::
Kaidan
(
Swift
::
NetworkFactories
*
networkFactories
,
QObject
*
parent
)
:
QObject
(
parent
)
Kaidan
::
Kaidan
(
Swift
::
NetworkFactories
*
networkFactories
,
QObject
*
parent
)
:
QObject
(
parent
)
{
netFactories
=
networkFactories
;
connected
=
false
;
netFactories
=
networkFactories
;
database
=
new
Database
();
database
->
openDatabase
();
if
(
database
->
needToConvert
())
database
->
convertDatabase
();
storages
=
new
Swift
::
MemoryStorages
(
Swift
::
PlatformCryptoProvider
::
create
());
messageController
=
new
MessageController
(
database
->
getDatabase
());
rosterController
=
new
RosterController
(
database
->
getDatabase
());
presenceController
=
new
PresenceController
();
vCardController
=
new
VCardController
();
serviceDiscoveryManager
=
new
ServiceDiscoveryManager
();
//
// Load settings data
...
...
@@ -70,15 +81,6 @@ Kaidan::Kaidan(Swift::NetworkFactories* networkFactories, QObject *parent) : QOb
// create/update the full jid
updateFullJid
();
// load controllers
messageController
=
new
MessageController
(
&
jid
);
rosterController
=
new
RosterController
();
presenceController
=
new
PresenceController
();
vCardController
=
new
VCardController
();
serviceDiscoveryManager
=
new
ServiceDiscoveryManager
();
storages
=
new
Swift
::
MemoryStorages
(
Swift
::
PlatformCryptoProvider
::
create
());
}
Kaidan
::~
Kaidan
()
...
...
@@ -216,7 +218,7 @@ void Kaidan::setChatPartner(QString chatPartner)
this
->
chatPartner
=
chatPartner
;
// upsate message controller
messageController
->
setChatPartner
(
&
chatPartner
);
messageController
->
setChatPartner
(
&
chatPartner
,
&
jid
);
rosterController
->
setChatPartner
(
&
chatPartner
);
emit
chatPartnerChanged
();
...
...
src/Kaidan.h
View file @
2e2ae1d5
...
...
@@ -31,6 +31,7 @@
#include <Swiften/Client/Client.h>
#include <Swiften/Client/ClientXMLTracer.h>
// Kaidan
#include "Database.h"
#include "RosterController.h"
#include "MessageController.h"
#include "PresenceController.h"
...
...
@@ -51,7 +52,7 @@ class Kaidan : public QObject
Q_PROPERTY
(
QString
chatPartner
READ
getChatPartner
WRITE
setChatPartner
NOTIFY
chatPartnerChanged
)
public:
Kaidan
(
Swift
::
NetworkFactories
*
networkFactories
,
QObject
*
parent
=
0
);
Kaidan
(
Swift
::
NetworkFactories
*
networkFactories
,
QObject
*
parent
=
0
);
~
Kaidan
();
Q_INVOKABLE
void
mainDisconnect
();
...
...
@@ -100,6 +101,7 @@ private:
Swift
::
NetworkFactories
*
netFactories
;
Swift
::
MemoryStorages
*
storages
;
Database
*
database
;
RosterController
*
rosterController
;
MessageController
*
messageController
;
PresenceController
*
presenceController
;
...
...
src/MessageController.cpp
View file @
2e2ae1d5
...
...
@@ -38,10 +38,9 @@
#include "MessageModel.h"
#include "Notifications.h"
MessageController
::
MessageController
(
QS
tring
*
ownJid_
,
QObject
*
parent
)
:
QObject
(
parent
)
MessageController
::
MessageController
(
QS
qlDatabase
*
database
,
QObject
*
parent
)
:
QObject
(
parent
)
{
ownJid
=
ownJid_
;
messageModel
=
new
MessageModel
();
messageModel
=
new
MessageModel
(
database
);
emit
messageModelChanged
();
}
...
...
@@ -61,7 +60,7 @@ MessageModel* MessageController::getMessageModel()
return
messageModel
;
}
void
MessageController
::
setChatPartner
(
QString
*
recipient
)
void
MessageController
::
setChatPartner
(
QString
*
recipient
,
QString
*
ownJid
)
{
// we have to use ownJid here, because this should also be usable when
// we're offline or we haven't connected already.
...
...
src/MessageController.h
View file @
2e2ae1d5
...
...
@@ -22,6 +22,7 @@
// Qt
#include <QObject>
#include <QSqlDatabase>
// Swiften
#include <Swiften/Client/Client.h>
#include <Swiften/Elements/Message.h>
...
...
@@ -35,13 +36,13 @@ class MessageController : public QObject
Q_PROPERTY
(
MessageModel
*
messageModel
READ
getMessageModel
NOTIFY
messageModelChanged
)
public:
MessageController
(
QS
tring
*
ownJid_
,
QObject
*
parent
=
0
);
MessageController
(
QS
qlDatabase
*
database
,
QObject
*
parent
=
0
);
~
MessageController
();
void
setClient
(
Swift
::
Client
*
client_
);
MessageModel
*
getMessageModel
();
void
setChatPartner
(
QString
*
recipient
);
void
setChatPartner
(
QString
*
recipient
,
QString
*
ownJid
);
void
sendMessage
(
QString
*
recipient_
,
QString
*
message_
);
signals:
...
...
src/MessageModel.cpp
View file @
2e2ae1d5
...
...
@@ -30,38 +30,10 @@
static
const
char
*
conversationsTableName
=
"Messages"
;
static
void
createTable
(
)
MessageModel
::
MessageModel
(
QSqlDatabase
*
database
,
QObject
*
parent
)
:
QSqlTableModel
(
parent
,
*
database
)
{
if
(
QSqlDatabase
::
database
().
tables
().
contains
(
conversationsTableName
))
{
// The table already exists; we don't need to do anything.
return
;
}
QSqlQuery
query
;
if
(
!
query
.
exec
(
"CREATE TABLE IF NOT EXISTS 'Messages' ("
"'author' TEXT NOT NULL,"
"'author_resource' TEXT,"
"'recipient' TEXT NOT NULL,"
"'recipient_resource' TEXT,"
"'timestamp' TEXT NOT NULL,"
"'message' TEXT NOT NULL,"
"'id' TEXT NOT NULL,"
"'isSent' BOOL,"
// is sent to server
"'isDelivered' BOOL,"
// message has arrived at other client
"FOREIGN KEY('author') REFERENCES Roster ('jid'),"
"FOREIGN KEY('recipient') REFERENCES Roster ('jid')"
")"
))
{
qFatal
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
}
MessageModel
::
MessageModel
(
QObject
*
parent
)
:
QSqlTableModel
(
parent
)
{
createTable
();
this
->
database
=
database
;
setTable
(
conversationsTableName
);
// sort in descending order of the timestamp column
setSort
(
4
,
Qt
::
DescendingOrder
);
...
...
@@ -99,14 +71,14 @@ QHash<int, QByteArray> MessageModel::roleNames() const
void
MessageModel
::
setMessageAsSent
(
const
QString
msgId
)
{
QSqlQuery
newQuery
;
QSqlQuery
newQuery
(
*
database
)
;
newQuery
.
exec
(
QString
(
"UPDATE 'Messages' SET 'isSent' = 1 WHERE id = '%1'"
).
arg
(
msgId
));
submitAll
();
}
void
MessageModel
::
setMessageAsDelivered
(
const
QString
msgId
)
{
QSqlQuery
newQuery
;
QSqlQuery
newQuery
(
*
database
)
;
newQuery
.
exec
(
QString
(
"UPDATE 'Messages' SET 'isDelivered' = 1 WHERE id = '%1'"
).
arg
(
msgId
));
submitAll
();
}
...
...
src/MessageModel.h
View file @
2e2ae1d5
...
...
@@ -27,7 +27,7 @@ class MessageModel : public QSqlTableModel
Q_OBJECT
public:
MessageModel
(
QObject
*
parent
=
0
);
MessageModel
(
QSqlDatabase
*
database
,
QObject
*
parent
=
0
);
QVariant
data
(
const
QModelIndex
&
index
,
int
role
)
const
Q_DECL_OVERRIDE
;
QHash
<
int
,
QByteArray
>
roleNames
()
const
Q_DECL_OVERRIDE
;
...
...
@@ -44,6 +44,7 @@ signals:
void
recipientChanged
();
private:
QSqlDatabase
*
database
;
};
#endif // MESSAGEMODEL_H
src/RosterController.cpp
View file @
2e2ae1d5
...
...
@@ -40,9 +40,10 @@
#include <boost/bind.hpp>
#include <boost/optional.hpp>
RosterController
::
RosterController
(
QObject
*
parent
)
:
QObject
(
parent
)
RosterController
::
RosterController
(
QSqlDatabase
*
database
,
QObject
*
parent
)
:
QObject
(
parent
)
{
rosterModel
=
new
RosterModel
();
rosterModel
=
new
RosterModel
(
database
);
chatPartner
=
QString
(
""
);
}
...
...
src/RosterController.h
View file @
2e2ae1d5
...
...
@@ -37,7 +37,7 @@ class RosterController : public QObject
Q_PROPERTY
(
RosterModel
*
rosterModel
READ
getRosterModel
NOTIFY
rosterModelChanged
)
public:
RosterController
(
QObject
*
parent
=
0
);
RosterController
(
QSqlDatabase
*
database
,
QObject
*
parent
=
0
);
~
RosterController
();
void
setClient
(
Swift
::
Client
*
client_
);
...
...
src/RosterModel.cpp
View file @
2e2ae1d5
...
...
@@ -24,37 +24,16 @@
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlDatabase>
#include <QSqlTableModel>
static
const
char
*
rosterTableName
=
"Roster"
;
static
void
createTable
()
RosterModel
::
RosterModel
(
QSqlDatabase
*
database
,
QObject
*
parent
)
:
QSqlTableModel
(
parent
,
*
database
)
{
if
(
QSqlDatabase
::
database
().
tables
().
contains
(
QStringLiteral
(
"Roster"
)))
{
// The table already exists; we don't need to do anything.
return
;
}
QSqlQuery
query
;
if
(
!
query
.
exec
(
"CREATE TABLE IF NOT EXISTS 'Roster' ("
"'jid' TEXT NOT NULL,"
"'name' TEXT NOT NULL,"
"'lastExchanged' TEXT NOT NULL,"
"'unreadMessages' INTEGER,"
"'lastMessage' TEXT,"
// < UNUSED v
"'lastOnline' TEXT,"
"'activity' TEXT,"
"'status' TEXT,"
"'mood' TEXT"
// < UNUSED ^
")"
))
{
qFatal
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
}
this
->
database
=
database
;
RosterModel
::
RosterModel
(
QObject
*
parent
)
:
QSqlTableModel
(
parent
)
{
createTable
();
setTable
(
rosterTableName
);
setEditStrategy
(
QSqlTableModel
::
OnManualSubmit
);
...
...
@@ -120,15 +99,19 @@ void RosterModel::insertContact(QString jid_, QString name_)
void
RosterModel
::
removeContactByJid
(
QString
jid_
)
{
QSqlQuery
newQuery
;
newQuery
.
exec
(
QString
(
"DELETE FROM 'Roster' WHERE jid = '%1'"
).
arg
(
jid_
));
QSqlQuery
query
(
*
database
);
if
(
!
query
.
exec
(
QString
(
"DELETE FROM 'Roster' WHERE jid = '%1'"
).
arg
(
jid_
)))
{
qDebug
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
submitAll
();
}
void
RosterModel
::
updateContactName
(
QString
jid_
,
QString
name_
)
{
QSqlQuery
newQuery
;
newQuery
.
exec
(
QString
(
"UPDATE 'Roster' SET name = '%1' WHERE jid = '%2'"
).
arg
(
name_
,
jid_
));
QSqlQuery
query
(
*
database
);
if
(
!
query
.
exec
(
QString
(
"UPDATE 'Roster' SET name = '%1' WHERE jid = '%2'"
).
arg
(
name_
,
jid_
)))
{
qDebug
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
submitAll
();
}
...
...
@@ -136,8 +119,10 @@ QStringList RosterModel::getJidList()
{
QStringList
retVar
;
QSqlQuery
query
;
query
.
exec
(
"SELECT jid FROM Roster"
);
QSqlQuery
query
(
*
database
);
if
(
!
query
.
exec
(
"SELECT jid FROM Roster"
))
{
qDebug
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
int
jidCol
=
query
.
record
().
indexOf
(
"jid"
);
...
...
@@ -149,23 +134,26 @@ QStringList RosterModel::getJidList()
void
RosterModel
::
removeListOfJids
(
QStringList
*
jidList
)
{
QSqlQuery
query
;
QSqlQuery
query
(
*
database
)
;
for
(
int
i
=
0
;
i
<
jidList
->
length
();
i
++
)
{
query
.
exec
(
QString
(
"DELETE FROM 'Roster' WHERE jid = '%1'"
).
arg
(
jidList
->
at
(
i
)));
if
(
!
query
.
exec
(
QString
(
"DELETE FROM 'Roster' WHERE jid = '%1'"
)
.
arg
(
jidList
->
at
(
i
))))
{
qDebug
(
"Failed to query database: %s"
,
qPrintable
(
query
.
lastError
().
text
()));
}
}
submitAll
();
}
void
RosterModel
::
setLastExchangedOfJid
(
QString
*
jid_
,
QString
*
date_
)
{
QSqlQuery
newQuery
;
QSqlQuery
newQuery
(
*
database
)
;
newQuery
.
exec
(
QString
(
"UPDATE 'Roster' SET lastExchanged = '%1' WHERE jid = '%2'"
).
arg
(
*
date_
,
*
jid_
));
submitAll
();
}
int
RosterModel
::
getUnreadMessageCountOfJid
(
const
QString
*
jid_
)
{
QSqlQuery
query
;
QSqlQuery
query
(
*
database
)
;
query
.
prepare
(
QString
(
"SELECT unreadMessages FROM Roster WHERE jid = '%1'"
).
arg
(
*
jid_
));
if
(
!
query
.
exec
())
{
...
...
@@ -179,7 +167,7 @@ int RosterModel::getUnreadMessageCountOfJid(const QString* jid_)
void
RosterModel
::
setUnreadMessageCountOfJid
(
const
QString
*
jid_
,
const
int
count_
)
{
QSqlQuery
query
;
QSqlQuery
query
(
*
database
)
;
query
.
prepare
(
QString
(
"UPDATE Roster SET unreadMessages = %1 WHERE jid = '%2'"
)
.
arg
(
QString
::
number
(
count_
),
*
jid_
));
...
...
@@ -196,7 +184,7 @@ void RosterModel::setUnreadMessageCountOfJid(const QString* jid_, const int coun
void
RosterModel
::
setLastMessageForJid
(
QString
*
jid
,
QString
*
message
)
{
QSqlQuery
query
;
QSqlQuery
query
(
*
database
)
;
query
.
prepare
(
QString
(
"UPDATE Roster SET lastMessage = %1 WHERE jid = '%2'"
)
.
arg
(
*
message
,
*
jid
));
...
...
src/RosterModel.h
View file @
2e2ae1d5
...
...
@@ -22,6 +22,7 @@
// Qt
#include <QObject>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QQmlListProperty>
...
...
@@ -29,7 +30,7 @@ class RosterModel : public QSqlTableModel
{
Q_OBJECT
public:
RosterModel
(
QObject
*
parent
=
0
);
RosterModel
(
QSqlDatabase
*
database
,
QObject
*
parent
=
0
);
QHash
<
int
,
QByteArray
>
roleNames
()
const
;
QVariant
data
(
const
QModelIndex
&
index
,
int
role
)
const
;
...
...
@@ -44,6 +45,9 @@ public:
int
getUnreadMessageCountOfJid
(
const
QString
*
jid_
);