diff options
-rw-r--r-- | src/enginio_client/enginiomodel.cpp | 8 | ||||
-rw-r--r-- | src/enginio_client/enginiomodelbase_p.h | 32 | ||||
-rw-r--r-- | tests/auto/enginiomodel/tst_enginiomodel.cpp | 4 |
3 files changed, 23 insertions, 21 deletions
diff --git a/src/enginio_client/enginiomodel.cpp b/src/enginio_client/enginiomodel.cpp index dd4f859..319c65a 100644 --- a/src/enginio_client/enginiomodel.cpp +++ b/src/enginio_client/enginiomodel.cpp @@ -159,8 +159,7 @@ EnginioModelBasePrivate::~EnginioModelBasePrivate() foreach (const QMetaObject::Connection &connection, _clientConnections) QObject::disconnect(connection); - foreach (const QMetaObject::Connection &connection, _repliesConnections) - QObject::disconnect(connection); + delete _replyConnectionConntext; } void EnginioModelBasePrivate::receivedNotification(QJsonObject data) @@ -250,9 +249,8 @@ void EnginioModelBasePrivate::receivedUpdateNotification(const QJsonObject &obje void EnginioModelBasePrivate::fullQueryReset(const QJsonArray &data) { - foreach (const QMetaObject::Connection &connection, _repliesConnections) - QObject::disconnect(connection); - _repliesConnections.clear(); + delete _replyConnectionConntext; + _replyConnectionConntext = new QObject(); q->beginResetModel(); _data = data; _attachedData.initFromArray(_data); diff --git a/src/enginio_client/enginiomodelbase_p.h b/src/enginio_client/enginiomodelbase_p.h index 386a67e..2f131b6 100644 --- a/src/enginio_client/enginiomodelbase_p.h +++ b/src/enginio_client/enginiomodelbase_p.h @@ -261,7 +261,7 @@ protected: EnginioClient::Operation _operation; EnginioModelBase *q; QVector<QMetaObject::Connection> _clientConnections; - QHash<const EnginioReplyBase*, QMetaObject::Connection> _repliesConnections; + QObject *_replyConnectionConntext; const static int IncrementalModelUpdate; typedef EnginioModelPrivateAttachedData AttachedData; @@ -410,6 +410,7 @@ public: : _enginio(0) , _operation() , q(q_ptr) + , _replyConnectionConntext(new QObject()) , _latestRequestedOffset(0) , _canFetchMore(false) , _rolesCounter(EnginioModel::SyncedRole) @@ -442,7 +443,7 @@ public: QNetworkReply *nreply = _enginio->create(aObject, _operation); EnginioReplyBase *ereply = _enginio->createReply(nreply); FinishedCreateRequest finishedRequest = { this, temporaryId, ereply }; - _repliesConnections.insert(ereply, QObject::connect(ereply, &EnginioReplyBase::dataChanged, finishedRequest)); + QObject::connect(ereply, &EnginioReplyBase::dataChanged, _replyConnectionConntext, finishedRequest); object[EnginioString::id] = temporaryId; const int row = _data.count(); AttachedData data(row, temporaryId); @@ -522,7 +523,7 @@ public: } QString id = tmp.first; FinishedRemoveRequest finishedRequest = { d._model, id, d._reply }; - QObject::connect(d._reply, &EnginioReplyBase::dataChanged, finishedRequest); + QObject::connect(d._reply, &EnginioReplyBase::dataChanged, d._model->_replyConnectionConntext, finishedRequest); EnginioReplyBase *ereply = d._model->removeNow(row, d._object, id); d.swapNetworkReply(ereply); } @@ -559,7 +560,7 @@ public: QNetworkReply *nreply = _enginio->remove(aOldObject, _operation); EnginioReplyBase *ereply = _enginio->createReply(nreply); FinishedRemoveRequest finishedRequest = { this, id, ereply }; - _repliesConnections.insert(ereply, QObject::connect(ereply, &EnginioReplyBase::dataChanged, finishedRequest)); + QObject::connect(ereply, &EnginioReplyBase::dataChanged, _replyConnectionConntext, finishedRequest); _attachedData.insertRequestId(ereply->requestId(), row); QVector<int> roles(1); roles.append(EnginioModel::SyncedRole); @@ -605,7 +606,7 @@ public: if (_canFetchMore) _latestRequestedOffset = query[EnginioString::limit].toDouble(); FinishedFullQueryRequest finshedRequest = { this, ereply }; - _repliesConnections.insert(ereply, QObject::connect(ereply, &EnginioReplyBase::dataChanged, finshedRequest)); + QObject::connect(ereply, &EnginioReplyBase::dataChanged, _replyConnectionConntext, finshedRequest); QObject::connect(ereply, &EnginioReplyBase::dataChanged, ereply, &EnginioReplyBase::deleteLater); } else { fullQueryReset(QJsonArray()); @@ -614,7 +615,6 @@ public: void finishedIncrementalUpdateRequest(const EnginioReplyBase *reply, const QJsonObject &query) { - _repliesConnections.remove(reply); Q_ASSERT(_canFetchMore); QJsonArray data(replyData(reply)[EnginioString::results].toArray()); int offset = query[EnginioString::offset].toDouble(); @@ -634,7 +634,8 @@ public: void finishedFullQueryRequest(const EnginioReplyBase *reply) { - _repliesConnections.remove(reply); + delete _replyConnectionConntext; + _replyConnectionConntext = new QObject(); fullQueryReset(replyData(reply)[EnginioString::results].toArray()); } @@ -642,7 +643,6 @@ public: void finishedCreateRequest(const EnginioReplyBase *reply, const QString &tmpId) { - _repliesConnections.remove(reply); if (_attachedData.markRequestIdAsHandled(reply->requestId())) return; // request was handled @@ -661,7 +661,9 @@ public: row = _attachedData.rowFromObjectId(id); } else { // we created the item but there is no sign of it. We need to check if we have more or - // less the same query + // less the same query, there is a chance that the value was lost in race between the + // reset and create. This is possible scenario that: + // send create -> send full query -> do query -> do create -> got query -> got create if (queryData(EnginioString::objectType) == replyData(reply)[EnginioString::objectType]) { // the type is the same so we can re-add it receivedCreateNotification(replyData(reply)); @@ -687,12 +689,15 @@ public: void finishedRemoveRequest(const EnginioReplyBase *response, const QString &id) { - _repliesConnections.remove(response); + if (!_attachedData.contains(id)) + return; // we do not know the object anymore, we are not interested in it's delete event + AttachedData &data = _attachedData.deref(id); if (_attachedData.markRequestIdAsHandled(response->requestId())) return; // request was handled + int row = data.row; if (row == DeletedRow || (response->networkError() != QNetworkReply::NoError && response->backendStatus() != 404)) { if (!data.ref) { @@ -707,7 +712,6 @@ public: void finishedUpdateRequest(const EnginioReplyBase *reply, const QString &id, const QJsonObject &oldValue) { - _repliesConnections.remove(reply); AttachedData &data = _attachedData.deref(id); if (_attachedData.markRequestIdAsHandled(reply->requestId())) @@ -762,7 +766,7 @@ public: } QString id = tmp.first; FinishedUpdateRequest finished = { d._model, id, d._object, d._reply }; - QObject::connect(d._reply, &EnginioReplyBase::dataChanged, finished); + QObject::connect(d._reply, &EnginioReplyBase::dataChanged, d._model->_replyConnectionConntext, finished); EnginioReplyBase *ereply = d._model->setDataNow(row, _value, _role, d._object, id); d.swapNetworkReply(ereply); } @@ -823,7 +827,7 @@ public: QNetworkReply *nreply = _enginio->update(aDeltaObject, _operation); EnginioReplyBase *ereply = _enginio->createReply(nreply); FinishedUpdateRequest finished = { this, id, oldObject, ereply }; - _repliesConnections.insert(ereply, QObject::connect(ereply, &EnginioReplyBase::dataChanged, finished)); + QObject::connect(ereply, &EnginioReplyBase::dataChanged, _replyConnectionConntext, finished); _attachedData.ref(id, row); _data.replace(row, newObject); _attachedData.insertRequestId(ereply->requestId(), row); @@ -895,7 +899,7 @@ public: EnginioReplyBase *ereply = _enginio->createReply(nreply); QObject::connect(ereply, &EnginioReplyBase::dataChanged, ereply, &EnginioReplyBase::deleteLater); FinishedIncrementalUpdateRequest finishedRequest = { this, query, ereply }; - _repliesConnections.insert(ereply, QObject::connect(ereply, &EnginioReplyBase::dataChanged, finishedRequest)); + QObject::connect(ereply, &EnginioReplyBase::dataChanged, _replyConnectionConntext, finishedRequest); } virtual QJsonObject replyData(const EnginioReplyBase *reply) const = 0; diff --git a/tests/auto/enginiomodel/tst_enginiomodel.cpp b/tests/auto/enginiomodel/tst_enginiomodel.cpp index e4c4741..a627f02 100644 --- a/tests/auto/enginiomodel/tst_enginiomodel.cpp +++ b/tests/auto/enginiomodel/tst_enginiomodel.cpp @@ -1224,7 +1224,7 @@ void tst_EnginioModel::appendBeforeInitialModelReset() EnginioClient client; client.setBackendId(_backendId); client.setServiceUrl(EnginioTests::TESTAPP_URL); - for (int i = 0; i < 12 ; ++i) { + for (int i = 0; i < 24 ; ++i) { QString objectType = "objects." + EnginioTests::CUSTOM_OBJECT1; QJsonObject query; query.insert("objectType", objectType); @@ -1254,7 +1254,7 @@ void tst_EnginioModel::delayedRequestBeforeInitialModelReset() EnginioClient client; client.setBackendId(_backendId); client.setServiceUrl(EnginioTests::TESTAPP_URL); - for (int i = 0; i < 12 ; ++i) { + for (int i = 0; i < 24 ; ++i) { QString objectType = "objects." + EnginioTests::CUSTOM_OBJECT1; QJsonObject query; query.insert("objectType", objectType); |