Skip to content

Commit

Permalink
Merge branch 'task/init-ChatDBInfo' into 'develop'
Browse files Browse the repository at this point in the history
CHT-963. ChatDBInfo should be initialized properly upon construction (RAII)

See merge request megachat/MEGAchat!1676
  • Loading branch information
jgandres committed Aug 4, 2023
2 parents 7fdce0b + 8afa40e commit 10ecba3
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 32 deletions.
22 changes: 11 additions & 11 deletions src/chatd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1945,8 +1945,8 @@ Chat::Chat(Connection& conn, const Id& chatid, Listener* listener,
initChat();
mAttachmentNodes = std::unique_ptr<FilteredHistory>(new FilteredHistory(*mDbInterface, *this));
ChatDbInfo&& info = getDbHistInfoAndInitOldestKnownMsgId();
mLastSeenId = info.lastSeenId;
mLastReceivedId = info.lastRecvId;
mLastSeenId = info.getLastSeenId();
mLastReceivedId = info.getlastRecvId();
mLastSeenIdx = mDbInterface->getIdxOfMsgidFromHistory(mLastSeenId);
mLastReceivedIdx = mDbInterface->getIdxOfMsgidFromHistory(mLastReceivedId);
std::string reactionSn = mDbInterface->getReactionSn();
Expand All @@ -1971,11 +1971,11 @@ Chat::Chat(Connection& conn, const Id& chatid, Listener* listener,
}
else
{
assert(info.newestDbIdx != CHATD_IDX_INVALID);
assert(info.getNewestDbIdx() != CHATD_IDX_INVALID);
mHasMoreHistoryInDb = true;
mForwardStart = info.newestDbIdx + 1;
mForwardStart = info.getNewestDbIdx() + 1;
CHATID_LOG_DEBUG("Db has local history: %s - %s (middle point: %u)",
ID_CSTR(info.oldestDbId), ID_CSTR(info.newestDbId), mForwardStart);
ID_CSTR(info.getOldestDbId()), ID_CSTR(info.getNewestDbId()), mForwardStart);
loadAndProcessUnsent();
getHistoryFromDb(initialHistoryFetchCount); // ensure we have a minimum set of messages loaded and ready
}
Expand Down Expand Up @@ -4211,25 +4211,25 @@ void Chat::removeManualSend(uint64_t rowid)
// after a reconnect, we tell the chatd the oldest and newest buffered message
void Chat::joinRangeHist(const ChatDbInfo& dbInfo)
{
assert(dbInfo.oldestDbId && dbInfo.newestDbId);
assert(!dbInfo.getOldestDbId().isNull() && !dbInfo.getNewestDbId().isNull());
mServerFetchState = kHistFetchingNewFromServer;

mFetchRequest.push(FetchType::kFetchMessages);
sendCommand(Command(OP_JOINRANGEHIST) + mChatId + dbInfo.oldestDbId + at(highnum()).id());
sendCommand(Command(OP_JOINRANGEHIST) + mChatId + dbInfo.getOldestDbId() + at(highnum()).id());
}

// after a reconnect, we tell the chatd the oldest and newest buffered message
void Chat::handlejoinRangeHist(const ChatDbInfo& dbInfo)
{
assert(previewMode());
assert(dbInfo.oldestDbId && dbInfo.newestDbId);
assert(!dbInfo.getOldestDbId().isNull() && !dbInfo.getNewestDbId().isNull());
mServerFetchState = kHistFetchingNewFromServer;

uint64_t ph = getPublicHandle();
Command comm (OP_HANDLEJOINRANGEHIST);
comm.append((const char*) &ph, Id::CHATLINKHANDLE);
mFetchRequest.push(FetchType::kFetchMessages);
sendCommand(comm + dbInfo.oldestDbId + at(highnum()).id());
sendCommand(comm + dbInfo.getOldestDbId() + at(highnum()).id());
}

Client::~Client()
Expand Down Expand Up @@ -5050,8 +5050,8 @@ ChatDbInfo Chat::getDbHistInfoAndInitOldestKnownMsgId()
{
ChatDbInfo info;
mDbInterface->getHistoryInfo(info);
mOldestKnownMsgId = info.oldestDbId; // if no db history, getHistoryInfo stores Id::null() at ChatDbInfo::oldestDbId
mOldestIdxInDb = info.oldestDbIdx; // if no db history, getHistoryInfo stores CHATD_IDX_INVALID at ChatDbInfo::oldestDbIdx
mOldestKnownMsgId = info.getOldestDbId(); // if no db history, getHistoryInfo stores Id::null() at ChatDbInfo::oldestDbId
mOldestIdxInDb = info.getOldestDbIdx(); // if no db history, getHistoryInfo stores CHATD_IDX_INVALID at ChatDbInfo::oldestDbIdx
return info;
}

Expand Down
43 changes: 38 additions & 5 deletions src/chatd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1661,12 +1661,45 @@ static inline const char* connStateToStr(Connection::State state)

struct ChatDbInfo
{
karere::Id oldestDbId;
karere::Id newestDbId;
public:
ChatDbInfo() = default;
~ChatDbInfo() = default;
ChatDbInfo(const ChatDbInfo& other) = default;
ChatDbInfo(ChatDbInfo&& other) = delete;
ChatDbInfo& operator = (const ChatDbInfo& other) = delete;
ChatDbInfo& operator = (ChatDbInfo&& other) = delete;

void reset()
{
oldestDbId = karere::Id::null();
newestDbId = karere::Id::null();
lastSeenId = karere::Id::null();
lastRecvId = karere::Id::null();
oldestDbIdx = CHATD_IDX_INVALID;
newestDbIdx = CHATD_IDX_RANGE_MIDDLE; // default value for newestDbIdx must be 0
}

Idx getOldestDbIdx() const { return oldestDbIdx; }
Idx getNewestDbIdx() const { return newestDbIdx; }
const karere::Id& getOldestDbId() const { return oldestDbId; }
const karere::Id& getNewestDbId() const { return newestDbId; }
const karere::Id& getLastSeenId() const { return lastSeenId; }
const karere::Id& getlastRecvId() const { return lastRecvId; }

void setOldestDbId(const karere::Id& id) { oldestDbId = id; }
void setNewestDbId(const karere::Id& id) { newestDbId = id; }
void setLastSeenId(const karere::Id& id) { lastSeenId = id; }
void setLastRecvId(const karere::Id& id) { lastRecvId = id; }
void setOldestDbIdx(const Idx idx) { oldestDbIdx = idx; }
void setNewestDbIdx(const Idx idx) { newestDbIdx = idx; }

private:
karere::Id oldestDbId = karere::Id::null();
karere::Id newestDbId = karere::Id::null();
karere::Id lastSeenId = karere::Id::null();
karere::Id lastRecvId = karere::Id::null();
Idx oldestDbIdx = CHATD_IDX_INVALID;
Idx newestDbIdx;
karere::Id lastSeenId;
karere::Id lastRecvId;
Idx newestDbIdx = CHATD_IDX_RANGE_MIDDLE;
};

class DbInterface
Expand Down
26 changes: 10 additions & 16 deletions src/chatdDb.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,31 @@ class ChatdSqliteDb: public chatd::DbInterface
SqliteStmt stmt(mDb, "select min(idx), max(idx) from history where chatid=?1");
stmt.bind(mChat.chatId()).step(); //will always return a row, even if table empty
auto minIdx = stmt.intCol(0); //WARNING: the chatd implementation uses uint32_t values for idx.
info.newestDbIdx = stmt.intCol(1);
info.setNewestDbIdx(stmt.intCol(1));
if (sqlite3_column_type(stmt, 0) == SQLITE_NULL) //no db history
{
/* TODO: add a method to reset ChatDbInfo values to invalid/default ones
* taking into account that newestDbIdx maybe could be set to CHATD_IDX_INVALID
* instead of 0 (check usages of newestDbIdx).
*/
void* voidmem = &info; // avoid compiler warning...
memset(voidmem, 0, sizeof(info)); // need to set oldestDbId to zero
info.oldestDbIdx = CHATD_IDX_INVALID; // set oldestDbIdx to invalid
info.reset(); // reset ChatDbInfo values to invalid/default ones
return;
}
info.oldestDbIdx = minIdx;
info.setOldestDbIdx(minIdx);
SqliteStmt stmt2(mDb, "select msgid from "+mHistTblName+" where chatid=?1 and idx=?2");
stmt2 << mChat.chatId() << minIdx;
stmt2.stepMustHaveData();
info.oldestDbId = stmt2.uint64Col(0);
stmt2.reset().bind(2, info.newestDbIdx);
info.setOldestDbId(stmt2.uint64Col(0));
stmt2.reset().bind(2, info.getNewestDbIdx());
stmt2.stepMustHaveData();
info.newestDbId = stmt2.uint64Col(0);
if (!info.newestDbId)
info.setNewestDbId(stmt2.uint64Col(0));
if (info.getNewestDbId().isNull())
{
assert(false); // if there's an oldest message, there should be always a newest message, even if it's the same one
CHATD_LOG_WARNING("Db: Newest msgid in db is null, telling chatd we don't have local history");
info.oldestDbId = karere::Id::null();
info.setOldestDbId(karere::Id::null());
}
SqliteStmt stmt3(mDb, "select last_seen, last_recv from chats where chatid=?");
stmt3 << mChat.chatId();
stmt3.stepMustHaveData();
info.lastSeenId = stmt3.uint64Col(0);
info.lastRecvId = stmt3.uint64Col(1);
info.setLastSeenId(stmt3.uint64Col(0));
info.setLastRecvId(stmt3.uint64Col(1));
}
void assertAffectedRowCount(int count, const char* opname=nullptr)
{
Expand Down

0 comments on commit 10ecba3

Please sign in to comment.