void Xep0313ReqIq::toXmlElementFromChild (QXmlStreamWriter *writer) const { QXmppIq::toXmlElementFromChild (writer); writer->writeStartElement ("query"); const auto endGuard = Util::MakeScopeGuard ([writer] { writer->writeEndElement (); }); writer->writeAttribute ("xmlns", Xep0313Manager::GetNsUri ()); if (!QueryID_.isEmpty ()) writer->writeAttribute ("queryid", QueryID_); if (JID_.isEmpty () && !Count_ && ItemId_.isEmpty ()) return; if (!JID_.isEmpty ()) { QXmppDataForm::Field formTypeField { QXmppDataForm::Field::HiddenField }; formTypeField.setKey ("FORM_TYPE"); formTypeField.setValue (Xep0313Manager::GetNsUri ()); QXmppDataForm::Field jidField { QXmppDataForm::Field::JidSingleField }; jidField.setKey ("with"); jidField.setValue (JID_); QXmppDataForm form { QXmppDataForm::Form }; form.setFields ({ formTypeField, jidField }); form.toXml (writer); } if (Count_ > 0 || !ItemId_.isEmpty ()) { QXmppResultSetQuery q; if (Count_ > 0) q.setMax (Count_); if (!ItemId_.isEmpty ()) { switch (Dir_) { case Direction::After: q.setAfter (ItemId_); break; case Direction::Before: q.setBefore (ItemId_); break; default: break; } } q.toXml (writer); } }
void Xep0313ReqIq::parseElementFromChild (const QDomElement& element) { QXmppIq::parseElementFromChild (element); const auto& queryElem = element.firstChildElement ("query"); QXmppDataForm form; form.parse (queryElem.firstChildElement ("x")); if (!form.isNull ()) for (const auto& field : form.fields ()) if (field.key () == "with") JID_ = field.value ().toString (); QXmppResultSetQuery q; q.parse (queryElem.firstChildElement ("set")); Count_ = q.max (); Dir_ = Direction::Unspecified; if (!q.after ().isNull ()) { ItemId_ = q.after ().toLatin1 (); Dir_ = Direction::After; } else if (!q.before ().isNull ()) { ItemId_ = q.before ().toLatin1 (); Dir_ = Direction::Before; } }
void tst_QXmppResultSet::testQuery() { QFETCH(QByteArray, xml); QFETCH(int, max); QFETCH(int, index); QFETCH(QString, before); QFETCH(QString, after); QXmppResultSetQuery iq; parsePacket(iq, xml); QCOMPARE(iq.max(), max); QCOMPARE(iq.index(), index); QCOMPARE(iq.before(), before); QCOMPARE(iq.before().isNull(), before.isNull()); QCOMPARE(iq.after(), after); QCOMPARE(iq.after().isNull(), after.isNull()); serializePacket(iq, xml); }
void rsmFilter(QDjangoQuerySet<T1> &qs, const QXmppResultSetQuery &rsmQuery, QList<T2> &results, QXmppResultSetReply &rsmReply) { // if count was requested, stop here if (rsmQuery.max() == 0) { rsmReply.setCount(qs.count()); return; } rsmReply.setCount(qs.size()); T1 result; if (rsmQuery.before().isNull()) { // page forwards bool rsmAfterReached = rsmQuery.after().isEmpty(); for (int i = 0; i < qs.size(); ++i) { if (rsmQuery.max() >= 0 && results.size() >= rsmQuery.max()) break; // fetch from database if (!qs.at(i, &result)) break; const QString uid = result.pk().toString(); // if an "after" was specified, check it was reached if (!rsmAfterReached) { if (uid == rsmQuery.after()) rsmAfterReached = true; continue; } if (results.isEmpty()) { rsmReply.setFirst(uid); rsmReply.setIndex(i); } rsmReply.setLast(uid); results << result; } } else { // page backwards bool rsmBeforeReached = rsmQuery.before().isEmpty(); for (int i = qs.size() - 1; i >= 0; --i) { if (rsmQuery.max() >= 0 && results.size() >= rsmQuery.max()) break; // fetch from database if (!qs.at(i, &result)) break; const QString uid = result.pk().toString(); // if a "before" was specified, check it was reached if (!rsmBeforeReached) { if (uid == rsmQuery.before()) rsmBeforeReached = true; continue; } if (results.isEmpty()) rsmReply.setLast(uid); rsmReply.setFirst(uid); rsmReply.setIndex(i); results.prepend(result); } } }