a method for setting states to messages

This commit is contained in:
Blue 2020-01-07 12:26:07 +03:00
parent ad1977f05f
commit 13a1970047
2 changed files with 72 additions and 34 deletions

View File

@ -173,28 +173,74 @@ Shared::Message Core::Archive::getElement(const QString& id)
throw Closed("getElement", jid.toStdString()); throw Closed("getElement", jid.toStdString());
} }
std::string strKey = id.toStdString();
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = strKey.size();
lmdbKey.mv_data = (char*)strKey.c_str();
MDB_txn *txn; MDB_txn *txn;
int rc;
mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn); mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
rc = mdb_get(txn, main, &lmdbKey, &lmdbData);
if (rc) { try {
qDebug() <<"Get error: " << mdb_strerror(rc); Shared::Message msg = getMessage(id.toStdString(), txn);
mdb_txn_abort(txn); mdb_txn_abort(txn);
throw NotFound(id.toStdString(), jid.toStdString()); return msg;
} else { } catch (...) {
mdb_txn_abort(txn);
throw;
}
}
Shared::Message Core::Archive::getMessage(const std::string& id, MDB_txn* txn)
{
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (char*)id.c_str();
int rc = mdb_get(txn, main, &lmdbKey, &lmdbData);
if (rc == 0) {
QByteArray ba((char*)lmdbData.mv_data, lmdbData.mv_size); QByteArray ba((char*)lmdbData.mv_data, lmdbData.mv_size);
QDataStream ds(&ba, QIODevice::ReadOnly); QDataStream ds(&ba, QIODevice::ReadOnly);
Shared::Message msg; Shared::Message msg;
msg.deserialize(ds); msg.deserialize(ds);
mdb_txn_abort(txn);
return msg; return msg;
} else if (rc == MDB_NOTFOUND) {
throw NotFound(id, jid.toStdString());
} else {
throw Unknown(jid.toStdString(), mdb_strerror(rc));
}
}
void Core::Archive::setMessageState(const QString& id, Shared::Message::State state)
{
if (!opened) {
throw Closed("setMessageState", jid.toStdString());
}
MDB_txn *txn;
mdb_txn_begin(environment, NULL, 0, &txn);
std::string strId(id.toStdString());
try {
Shared::Message msg = getMessage(strId, txn);
msg.setState(state);
MDB_val lmdbKey, lmdbData;
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
msg.serialize(ds);
lmdbKey.mv_size = strId.size();
lmdbKey.mv_data = (char*)strId.c_str();
lmdbData.mv_size = ba.size();
lmdbData.mv_data = (uint8_t*)ba.data();
int rc = mdb_put(txn, main, &lmdbKey, &lmdbData, 0);
if (rc == 0) {
rc = mdb_txn_commit(txn);
} else {
mdb_txn_abort(txn);
throw Unknown(jid.toStdString(), mdb_strerror(rc));
}
} catch (...) {
mdb_txn_abort(txn);
throw;
} }
} }
@ -344,8 +390,8 @@ std::list<Shared::Message> Core::Archive::getBefore(int count, const QString& id
MDB_val lmdbKey, lmdbData; MDB_val lmdbKey, lmdbData;
int rc; int rc;
rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn); rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
if (id == "") {
rc = mdb_cursor_open(txn, order, &cursor); rc = mdb_cursor_open(txn, order, &cursor);
if (id == "") {
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST);
if (rc) { if (rc) {
qDebug() << "Error getting before" << mdb_strerror(rc) << ", id:" << id; qDebug() << "Error getting before" << mdb_strerror(rc) << ", id:" << id;
@ -356,40 +402,29 @@ std::list<Shared::Message> Core::Archive::getBefore(int count, const QString& id
} }
} else { } else {
std::string stdId(id.toStdString()); std::string stdId(id.toStdString());
lmdbKey.mv_size = stdId.size(); try {
lmdbKey.mv_data = (char*)stdId.c_str(); Shared::Message msg = getMessage(stdId, txn);
rc = mdb_get(txn, main, &lmdbKey, &lmdbData);
if (rc) {
qDebug() <<"Error getting before: no reference message" << mdb_strerror(rc) << ", id:" << id;
mdb_txn_abort(txn);
throw NotFound(stdId, jid.toStdString());
} else {
QByteArray ba((char*)lmdbData.mv_data, lmdbData.mv_size);
QDataStream ds(&ba, QIODevice::ReadOnly);
Shared::Message msg;
msg.deserialize(ds);
quint64 stamp = msg.getTime().toMSecsSinceEpoch(); quint64 stamp = msg.getTime().toMSecsSinceEpoch();
lmdbKey.mv_data = (quint8*)&stamp; lmdbKey.mv_data = (quint8*)&stamp;
lmdbKey.mv_size = 8; lmdbKey.mv_size = 8;
rc = mdb_cursor_open(txn, order, &cursor);
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_SET); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_SET);
if (rc) { if (rc) {
qDebug() << "Error getting before: couldn't set " << mdb_strerror(rc); qDebug() << "Error getting before: couldn't set " << mdb_strerror(rc);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
throw NotFound(stdId, jid.toStdString()); throw NotFound(stdId, jid.toStdString());
} else { } else {
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_PREV); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_PREV);
if (rc) { if (rc) {
qDebug() << "Error getting before, couldn't prev " << mdb_strerror(rc); qDebug() << "Error getting before, couldn't prev " << mdb_strerror(rc);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
throw NotFound(stdId, jid.toStdString()); throw NotFound(stdId, jid.toStdString());
} }
} }
} catch (...) {
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
throw;
} }
} }
@ -401,6 +436,7 @@ std::list<Shared::Message> Core::Archive::getBefore(int count, const QString& id
if (rc) { if (rc) {
qDebug() <<"Get error: " << mdb_strerror(rc); qDebug() <<"Get error: " << mdb_strerror(rc);
std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size); std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size);
mdb_cursor_close(cursor);
mdb_txn_abort(txn); mdb_txn_abort(txn);
throw NotFound(sId, jid.toStdString()); throw NotFound(sId, jid.toStdString());
} else { } else {
@ -687,9 +723,9 @@ bool Core::Archive::readAvatarInfo(Core::Archive::AvatarInfo& target, const QStr
bool success = readAvatarInfo(target, res, txn); bool success = readAvatarInfo(target, res, txn);
mdb_txn_abort(txn); mdb_txn_abort(txn);
return success; return success;
} catch (const std::exception& e) { } catch (...) {
mdb_txn_abort(txn); mdb_txn_abort(txn);
throw e; throw;
} }
} }

View File

@ -46,6 +46,7 @@ public:
bool addElement(const Shared::Message& message); bool addElement(const Shared::Message& message);
unsigned int addElements(const std::list<Shared::Message>& messages); unsigned int addElements(const std::list<Shared::Message>& messages);
Shared::Message getElement(const QString& id); Shared::Message getElement(const QString& id);
void setMessageState(const QString& id, Shared::Message::State state);
Shared::Message oldest(); Shared::Message oldest();
QString oldestId(); QString oldestId();
Shared::Message newest(); Shared::Message newest();
@ -181,6 +182,7 @@ private:
void printOrder(); void printOrder();
void printKeys(); void printKeys();
bool dropAvatar(const std::string& resource); bool dropAvatar(const std::string& resource);
Shared::Message getMessage(const std::string& id, MDB_txn* txn);
}; };
} }