Commit fbc32aa3 authored by Konrad Czapla's avatar Konrad Czapla
Browse files

Limit support for FETCH command

parent ea2343ab
......@@ -34,7 +34,7 @@ bool ItemFetchHandler::parseStream()
CacheCleanerInhibitor inhibitor(akonadi());
ItemFetchHelper fetchHelper(connection(), context, cmd.scope(), cmd.itemFetchScope(), cmd.tagFetchScope(), akonadi());
ItemFetchHelper fetchHelper(connection(), context, cmd.scope(), cmd.itemFetchScope(), cmd.tagFetchScope(), akonadi(), cmd.itemsLimit());
if (!fetchHelper.fetchItems()) {
return failureResponse(QStringLiteral("Failed to fetch items"));
}
......
......@@ -58,8 +58,9 @@ ItemFetchHelper::ItemFetchHelper(Connection *connection,
const Scope &scope,
const Protocol::ItemFetchScope &itemFetchScope,
const Protocol::TagFetchScope &tagFetchScope,
AkonadiServer &akonadi)
: ItemFetchHelper(connection, connection->context(), scope, itemFetchScope, tagFetchScope, akonadi)
AkonadiServer &akonadi,
const Protocol::FetchLimit &itemsLimit)
: ItemFetchHelper(connection, connection->context(), scope, itemFetchScope, tagFetchScope, akonadi, itemsLimit)
{
}
......@@ -68,13 +69,17 @@ ItemFetchHelper::ItemFetchHelper(Connection *connection,
const Scope &scope,
const Protocol::ItemFetchScope &itemFetchScope,
const Protocol::TagFetchScope &tagFetchScope,
AkonadiServer &akonadi)
AkonadiServer &akonadi,
const Protocol::FetchLimit &itemsLimit)
: mConnection(connection)
, mContext(context)
, mScope(scope)
, mItemFetchScope(itemFetchScope)
, mTagFetchScope(tagFetchScope)
, mAkonadi(akonadi)
, mItemsLimit(itemsLimit)
, mItemQuery(PimItem::tableName())
, mPimItemQueryAlias(QLatin1String("pimItem_alias"))
{
std::fill(mItemQueryColumnMap, mItemQueryColumnMap + ItemQueryColumnCount, -1);
}
......@@ -97,17 +102,20 @@ QSqlQuery ItemFetchHelper::buildPartQuery(const QVector<QByteArray> &partList, b
{
/// TODO: merge with ItemQuery
QueryBuilder partQuery(PimItem::tableName());
if (mItemsLimit.limit() > 0) {
partQuery = QueryBuilder(mItemQuery.query(), mPimItemQueryAlias);
}
if (!partList.isEmpty() || allPayload || allAttrs) {
partQuery.addJoin(QueryBuilder::InnerJoin, Part::tableName(), PimItem::idFullColumnName(), Part::pimItemIdFullColumnName());
partQuery.addColumn(PimItem::idFullColumnName());
partQuery.addJoin(QueryBuilder::InnerJoin, Part::tableName(), partQuery.getTable() + QLatin1Char('.') + PimItem::idColumn(), Part::pimItemIdFullColumnName());
partQuery.addColumn(partQuery.getTable() + QLatin1Char('.') + PimItem::idColumn());
partQuery.addColumn(Part::partTypeIdFullColumnName());
partQuery.addColumn(Part::dataFullColumnName());
partQuery.addColumn(Part::storageFullColumnName());
partQuery.addColumn(Part::versionFullColumnName());
partQuery.addColumn(Part::datasizeFullColumnName());
partQuery.addSortColumn(PimItem::idFullColumnName(), Query::Descending);
partQuery.addSortColumn(partQuery.getTable() + QLatin1Char('.') + PimItem::idColumn(), Query::Descending);
if (!partList.isEmpty() || allPayload || allAttrs) {
Query::Condition cond(Query::Or);
......@@ -142,12 +150,10 @@ QSqlQuery ItemFetchHelper::buildPartQuery(const QVector<QByteArray> &partList, b
QSqlQuery ItemFetchHelper::buildItemQuery()
{
QueryBuilder itemQuery(PimItem::tableName());
int column = 0;
#define ADD_COLUMN(colName, colId) \
{ \
itemQuery.addColumn(colName); \
mItemQuery.addColumn(colName); \
mItemQueryColumnMap[colId] = column++; \
}
ADD_COLUMN(PimItem::idFullColumnName(), ItemQueryPimItemIdColumn);
......@@ -171,21 +177,24 @@ QSqlQuery ItemFetchHelper::buildItemQuery()
}
#undef ADD_COLUMN
itemQuery.addSortColumn(PimItem::idFullColumnName(), Query::Descending);
mItemQuery.addSortColumn(PimItem::idFullColumnName(), static_cast<Query::SortOrder>(mItemsLimit.sortOrder()));
if (mItemsLimit.limit() > 0) {
mItemQuery.setLimit(mItemsLimit.limit(), mItemsLimit.limitOffset());
}
ItemQueryHelper::scopeToQuery(mScope, mContext, itemQuery);
ItemQueryHelper::scopeToQuery(mScope, mContext, mItemQuery);
if (mItemFetchScope.changedSince().isValid()) {
itemQuery.addValueCondition(PimItem::datetimeFullColumnName(), Query::GreaterOrEqual, mItemFetchScope.changedSince().toUTC());
mItemQuery.addValueCondition(PimItem::datetimeFullColumnName(), Query::GreaterOrEqual, mItemFetchScope.changedSince().toUTC());
}
if (!itemQuery.exec()) {
if (!mItemQuery.exec()) {
throw HandlerException("Unable to list items");
}
itemQuery.query().next();
mItemQuery.query().next();
return itemQuery.query();
return mItemQuery.query();
}
enum FlagQueryColumns {
......@@ -196,12 +205,17 @@ enum FlagQueryColumns {
QSqlQuery ItemFetchHelper::buildFlagQuery()
{
QueryBuilder flagQuery(PimItem::tableName());
flagQuery.addJoin(QueryBuilder::InnerJoin, PimItemFlagRelation::tableName(), PimItem::idFullColumnName(), PimItemFlagRelation::leftFullColumnName());
flagQuery.addColumn(PimItem::idFullColumnName());
if (mItemsLimit.limit() > 0) {
flagQuery = QueryBuilder(mItemQuery.query(), mPimItemQueryAlias);
}
flagQuery.addJoin(QueryBuilder::InnerJoin, PimItemFlagRelation::tableName(), flagQuery.getTable() + QLatin1Char('.') + PimItem::idColumn(), PimItemFlagRelation::leftFullColumnName());
flagQuery.addColumn(flagQuery.getTable() + QLatin1Char('.') + PimItem::idColumn());
flagQuery.addColumn(PimItemFlagRelation::rightFullColumnName());
ItemQueryHelper::scopeToQuery(mScope, mContext, flagQuery);
flagQuery.addSortColumn(PimItem::idFullColumnName(), Query::Descending);
flagQuery.addSortColumn(flagQuery.getTable() + QLatin1Char('.') + PimItem::idColumn(), Query::Descending);
if (!flagQuery.exec()) {
throw HandlerException("Unable to retrieve item flags");
......@@ -220,13 +234,17 @@ enum TagQueryColumns {
QSqlQuery ItemFetchHelper::buildTagQuery()
{
QueryBuilder tagQuery(PimItem::tableName());
tagQuery.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(), PimItem::idFullColumnName(), PimItemTagRelation::leftFullColumnName());
if (mItemsLimit.limit() > 0) {
tagQuery = QueryBuilder(mItemQuery.query(), mPimItemQueryAlias);
}
tagQuery.addJoin(QueryBuilder::InnerJoin, PimItemTagRelation::tableName(), tagQuery.getTable() + QLatin1Char('.') + PimItem::idColumn(), PimItemTagRelation::leftFullColumnName());
tagQuery.addJoin(QueryBuilder::InnerJoin, Tag::tableName(), Tag::idFullColumnName(), PimItemTagRelation::rightFullColumnName());
tagQuery.addColumn(PimItem::idFullColumnName());
tagQuery.addColumn(tagQuery.getTable() + QLatin1Char('.') + PimItem::idColumn());
tagQuery.addColumn(Tag::idFullColumnName());
ItemQueryHelper::scopeToQuery(mScope, mContext, tagQuery);
tagQuery.addSortColumn(PimItem::idFullColumnName(), Query::Descending);
tagQuery.addSortColumn(tagQuery.getTable() + QLatin1Char('.') + PimItem::idColumn(), Query::Descending);
if (!tagQuery.exec()) {
throw HandlerException("Unable to retrieve item tags");
......@@ -245,14 +263,18 @@ enum VRefQueryColumns {
QSqlQuery ItemFetchHelper::buildVRefQuery()
{
QueryBuilder vRefQuery(PimItem::tableName());
if(mItemsLimit.limit() > 0) {
vRefQuery = QueryBuilder(mItemQuery.query(), mPimItemQueryAlias);
}
vRefQuery.addJoin(QueryBuilder::LeftJoin,
CollectionPimItemRelation::tableName(),
CollectionPimItemRelation::rightFullColumnName(),
PimItem::idFullColumnName());
vRefQuery.getTable() + QLatin1Char('.') + PimItem::idColumn());
vRefQuery.addColumn(CollectionPimItemRelation::leftFullColumnName());
vRefQuery.addColumn(CollectionPimItemRelation::rightFullColumnName());
ItemQueryHelper::scopeToQuery(mScope, mContext, vRefQuery);
vRefQuery.addSortColumn(PimItem::idFullColumnName(), Query::Descending);
vRefQuery.addSortColumn(vRefQuery.getTable() + QLatin1Char('.') + PimItem::idColumn(), Query::Descending);
if (!vRefQuery.exec()) {
throw HandlerException("Unable to retrieve virtual references");
......
......@@ -33,13 +33,15 @@ public:
const Scope &scope,
const Protocol::ItemFetchScope &itemFetchScope,
const Protocol::TagFetchScope &tagFagScope,
AkonadiServer &akonadi);
AkonadiServer &akonadi,
const Protocol::FetchLimit &itemsLimit = Protocol::FetchLimit());
ItemFetchHelper(Connection *connection,
const CommandContext &context,
const Scope &scope,
const Protocol::ItemFetchScope &itemFetchScope,
const Protocol::TagFetchScope &tagFetchScope,
AkonadiServer &akonadi);
AkonadiServer &akonadi,
const Protocol::FetchLimit &itemsLimit = Protocol::FetchLimit());
bool fetchItems(std::function<void(Protocol::FetchItemsResponse &&)> &&callback = {});
......@@ -84,6 +86,9 @@ private:
int mItemQueryColumnMap[ItemQueryColumnCount];
bool mUpdateATimeEnabled = true;
AkonadiServer &mAkonadi;
Protocol::FetchLimit mItemsLimit;
QueryBuilder mItemQuery;
QString mPimItemQueryAlias;
friend class ::ItemFetchHelperTest;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment