Logo Search packages:      
Sourcecode: akonadi version File versions  Download package

bool Fetch::handleLine ( const QByteArray &  line  )  [virtual]

Process one line of input.

Parameters:
line The input.
Returns:
false if the handler expects to read more data from the client, true otherwise.

Reimplemented from Akonadi::Handler.

Definition at line 130 of file fetch.cpp.

References Akonadi::QueryBuilder::addColumn(), Akonadi::QueryBuilder::addColumnCondition(), Akonadi::QueryBuilder::addSortColumn(), Akonadi::QueryBuilder::addTable(), Akonadi::QueryBuilder::exec(), Akonadi::Handler::failureResponse(), Akonadi::Handler::imapSetToQuery(), Akonadi::ImapParser::join(), Akonadi::QueryBuilder::query(), Akonadi::ImapParser::quote(), Akonadi::Handler::responseAvailable(), Akonadi::Response::setString(), Akonadi::Response::setSuccess(), Akonadi::Response::setTag(), Akonadi::Response::setUntagged(), and Akonadi::Handler::tag().

{
  try {
    parseCommand( line );

    triggerOnDemandFetch();

    buildItemQuery();

    // build flag query if needed
    QueryBuilder flagQuery;
    if ( mRequestedParts.contains( "FLAGS" ) ) {
      flagQuery.addTable( PimItem::tableName() );
      flagQuery.addTable( PimItemFlagRelation::tableName() );
      flagQuery.addTable( Flag::tableName() );
      flagQuery.addColumn( PimItem::idFullColumnName() );
      flagQuery.addColumn( Flag::nameFullColumnName() );
      flagQuery.addColumnCondition( PimItem::idFullColumnName(), Query::Equals, PimItemFlagRelation::leftFullColumnName() );
      flagQuery.addColumnCondition( Flag::idFullColumnName(), Query::Equals, PimItemFlagRelation::rightFullColumnName() );
      imapSetToQuery( mSet, mIsUidFetch, flagQuery );
      flagQuery.addSortColumn( PimItem::idFullColumnName(), Query::Ascending );

      if ( !flagQuery.exec() )
        return failureResponse( "Unable to retrieve item flags" );
      flagQuery.query().next();
    }
    const int flagQueryIdColumn = 0;
    const int flagQueryNameColumn = 1;

    // retrieve missing parts
    QStringList partList, payloadList;
    foreach( const QByteArray &b, mRequestedParts ) {
      // filter out non-part attributes
      if ( b == "REV" || b == "FLAGS" || b == "UID" || b == "REMOTEID" )
        continue;
      partList << QString::fromLatin1( b );
      if ( b.startsWith( "PLD:" ) )
        payloadList << QString::fromLatin1( b );
    }
    retrieveMissingPayloads( payloadList );

    // build part query if needed
    QueryBuilder partQuery;
    if ( !partList.isEmpty() || mFullPayload || mAllAttrs ) {
      partQuery = buildPartQuery( partList, mFullPayload, mAllAttrs );
      if ( !partQuery.exec() )
        return failureResponse( "Unable to retrieve item parts" );
      partQuery.query().next();
    }

    // build responses
    Response response;
    response.setUntagged();
    while ( mItemQuery.query().isValid() ) {
      const qint64 pimItemId = mItemQuery.query().value( itemQueryIdColumn ).toLongLong();
      const int pimItemRev = mItemQuery.query().value( itemQueryRevColumn ).toInt();
      QList<QByteArray> attributes;
      attributes.append( "UID " + QByteArray::number( pimItemId ) );
      attributes.append( "REV " + QByteArray::number( pimItemRev ) );
      attributes.append( "REMOTEID " + ImapParser::quote( mItemQuery.query().value( itemQueryRidColumn ).toString().toUtf8() ) );
      attributes.append( "MIMETYPE " + ImapParser::quote( mItemQuery.query().value( itemQueryMimeTypeColumn ).toString().toUtf8() ) );

      if ( mRequestedParts.contains( "FLAGS" ) ) {
        QList<QByteArray> flags;
        while ( flagQuery.query().isValid() ) {
          const qint64 id = flagQuery.query().value( flagQueryIdColumn ).toLongLong();
          if ( id < pimItemId ) {
            flagQuery.query().next();
            continue;
          } else if ( id > pimItemId ) {
            break;
          }
          flags << flagQuery.query().value( flagQueryNameColumn ).toString().toUtf8();
          flagQuery.query().next();
        }
        attributes.append( "FLAGS (" + ImapParser::join( flags, " " ) + ')' );
      }

      while ( partQuery.query().isValid() ) {
        const qint64 id = partQuery.query().value( partQueryIdColumn ).toLongLong();
        if ( id < pimItemId ) {
          partQuery.query().next();
          continue;
        } else if ( id > pimItemId ) {
          break;
        }
        QByteArray partName = partQuery.query().value( partQueryNameColumn ).toString().toUtf8();
        QByteArray part = partQuery.query().value( partQueryNameColumn ).toString().toUtf8();
        QByteArray data = partQuery.query().value( partQueryDataColumn ).toByteArray();
        int version = partQuery.query().value( partQueryVersionColumn ).toInt();
        if ( version != 0 ) { // '0' is the default, so don't send it
          part += "[" + QByteArray::number( version ) + "]";
        }
        if ( data.isNull() ) {
          part += " NIL";
        } else if ( data.isEmpty() ) {
          part += " \"\"";
        } else {
          part += " {" + QByteArray::number( data.length() ) + "}\n";
          part += data;
        }

        if ( mRequestedParts.contains( partName ) || mFullPayload || mAllAttrs )
          attributes << part;

        partQuery.query().next();
      }

      // IMAP protocol violation: should actually be the sequence number
      QByteArray attr = QByteArray::number( pimItemId ) + " FETCH (";
      attr += ImapParser::join( attributes, " " ) + ')';
      response.setUntagged();
      response.setString( attr );
      emit responseAvailable( response );

      mItemQuery.query().next();
    }

    // update atime
    updateItemAccessTime();

  } catch ( std::exception &e ) {
    return failureResponse( e.what() );
  }

  Response response;
  response.setTag( tag() );
  response.setSuccess();
  if ( mIsUidFetch )
    response.setString( "UID FETCH completed" );
  else
    response.setString( "FETCH completed" );
  emit responseAvailable( response );
  deleteLater();
  return true;
}


Generated by  Doxygen 1.6.0   Back to index