@ -380,6 +380,25 @@ MessageState getMessageState(bool isPending, bool isBroken)
@@ -380,6 +380,25 @@ MessageState getMessageState(bool isPending, bool isBroken)
}
return messageState ;
}
QString generatePeerIdString ( ToxPk const & pk )
{
return QString ( " (SELECT id FROM peers WHERE public_key = '%1') " ).arg(pk.toString()) ;
}
RawDatabase : : Query generateEnsurePkInPeers ( ToxPk const & pk )
{
return RawDatabase : : Query { QStringLiteral ( " INSERT OR IGNORE INTO peers (public_key) "
" VALUES ('%1') " ) . arg ( pk . toString ( ) ) } ;
}
RawDatabase : : Query generateUpdateAlias ( ToxPk const & pk , QString const & dispName )
{
return RawDatabase : : Query (
QString ( " INSERT OR IGNORE INTO aliases (owner, display_name) VALUES (%1, ?); " ) . arg ( generatePeerIdString ( pk ) ) ,
{ dispName . toUtf8 ( ) } ) ;
}
} // namespace
/**
@ -424,15 +443,6 @@ History::History(std::shared_ptr<RawDatabase> db_)
@@ -424,15 +443,6 @@ History::History(std::shared_ptr<RawDatabase> db_)
connect ( this , & History : : fileInsertionReady , this , & History : : onFileInsertionReady ) ;
connect ( this , & History : : fileInserted , this , & History : : onFileInserted ) ;
// Cache our current peers
db - > execLater ( RawDatabase : : Query { " SELECT public_key, id FROM peers; " ,
[ this ] ( const QVector < QVariant > & row ) {
// HACK: we previously accidentally put Tox IDs in the db. So instead of
// constructing as a ToxPk which will enforce the correct length, construct
// as ToxId which will allow either length, and then convert to ToxPk.
peers [ ToxId { QByteArray : : fromHex ( row [ 0 ] . toByteArray ( ) ) } . getPublicKey ( ) ] = row [ 1 ] . toInt ( ) ;
} } ) ;
}
History : : ~ History ( )
@ -497,12 +507,6 @@ void History::removeFriendHistory(const ToxPk& friendPk)
@@ -497,12 +507,6 @@ void History::removeFriendHistory(const ToxPk& friendPk)
return ;
}
if ( ! peers . contains ( friendPk ) ) {
return ;
}
int64_t id = peers [ friendPk ] ;
QString queryText = QString ( " DELETE FROM faux_offline_pending "
" WHERE faux_offline_pending.id IN ( "
" SELECT faux_offline_pending.id FROM faux_offline_pending "
@ -520,11 +524,9 @@ void History::removeFriendHistory(const ToxPk& friendPk)
@@ -520,11 +524,9 @@ void History::removeFriendHistory(const ToxPk& friendPk)
" DELETE FROM peers WHERE id=%1; "
" DELETE FROM file_transfers WHERE chat_id=%1; "
" VACUUM; " )
. arg ( id ) ;
. arg ( generatePeerIdStr ing ( frien dPk ) ) ;
if ( db - > execNow ( queryText ) ) {
peers . remove ( friendPk ) ;
} else {
if ( ! db - > execNow ( queryText ) ) {
qWarning ( ) < < " Failed to remove friend's history " ;
}
}
@ -546,60 +548,20 @@ History::generateNewMessageQueries(const ToxPk& friendPk, const QString& message
@@ -546,60 +548,20 @@ History::generateNewMessageQueries(const ToxPk& friendPk, const QString& message
{
QVector < RawDatabase : : Query > queries ;
// Get the db id of the peer we're chatting with
int64_t peerId ;
if ( peers . contains ( friendPk ) ) {
peerId = ( peers ) [ friendPk ] ;
} else {
if ( peers . isEmpty ( ) ) {
peerId = 0 ;
} else {
peerId = * std : : max_element ( peers . begin ( ) , peers . end ( ) ) + 1 ;
}
( peers ) [ friendPk ] = peerId ;
queries + = RawDatabase : : Query ( ( " INSERT INTO peers (id, public_key) "
" VALUES (%1, ' "
+ friendPk . toString ( ) + " '); " )
. arg ( peerId ) ) ;
}
// Get the db id of the sender of the message
int64_t senderId ;
if ( peers . contains ( sender ) ) {
senderId = ( peers ) [ sender ] ;
} else {
if ( peers . isEmpty ( ) ) {
senderId = 0 ;
} else {
senderId = * std : : max_element ( peers . begin ( ) , peers . end ( ) ) + 1 ;
}
( peers ) [ sender ] = senderId ;
queries + = RawDatabase : : Query { ( " INSERT INTO peers (id, public_key) "
" VALUES (%1, ' "
+ sender . toString ( ) + " '); " )
. arg ( senderId ) } ;
}
queries + = RawDatabase : : Query (
QString ( " INSERT OR IGNORE INTO aliases (owner, display_name) VALUES (%1, ?); " ) . arg ( senderId ) ,
{ dispName . toUtf8 ( ) } ) ;
queries + = generateEnsurePkInPeers ( friendPk ) ;
queries + = generateEnsurePkInPeers ( sender ) ;
queries + = generateUpdateAlias ( sender , dispName ) ;
// If the alias already existed, the insert will ignore the conflict and last_insert_rowid()
// will return garbage,
// so we have to check changes() and manually fetch the row ID in this case
queries + =
RawDatabase : : Query ( QString (
" INSERT INTO history (timestamp, chat_id, message, sender_alias) "
" VALUES (%1, %2, ?, ( "
" CASE WHEN changes() IS 0 THEN ( "
" SELECT id FROM aliases WHERE owner=%3 AND display_name=?) "
" ELSE last_insert_rowid() END "
" )); " )
" ); " )
. arg ( time . toMSecsSinceEpoch ( ) )
. arg ( peerId )
. arg ( senderId ) ,
. arg ( generatePeerIdString ( friendPk ) )
. arg ( generatePeerIdString ( sender ) ) ,
{ message . toUtf8 ( ) , dispName . toUtf8 ( ) } , insertIdCallback ) ;
if ( ! isDelivered ) {
@ -617,8 +579,6 @@ void History::onFileInsertionReady(FileDbInsertionData data)
@@ -617,8 +579,6 @@ void History::onFileInsertionReady(FileDbInsertionData data)
QVector < RawDatabase : : Query > queries ;
std : : weak_ptr < History > weakThis = shared_from_this ( ) ;
// peerId is guaranteed to be inserted since we just used it in addNewMessage
auto peerId = peers [ data . friendPk ] ;
// Copy to pass into labmda for later
auto fileId = data . fileId ;
queries + =
@ -626,7 +586,7 @@ void History::onFileInsertionReady(FileDbInsertionData data)
@@ -626,7 +586,7 @@ void History::onFileInsertionReady(FileDbInsertionData data)
" INSERT INTO file_transfers (chat_id, file_restart_id, "
" file_path, file_name, file_hash, file_size, direction, file_state) "
" VALUES (%1, ?, ?, ?, ?, %2, %3, %4); " )
. arg ( peerId )
. arg ( generatePeerIdString ( data . friendPk ) )
. arg ( data . size )
. arg ( static_cast < int > ( data . direction ) )
. arg ( ToxFile : : CANCELED ) ,