[Kde-pim] SEGV reading Akonadi::Attribute from retrieveItem

Daniel Vrátil dvratil at redhat.com
Mon Jun 9 09:34:08 BST 2014


On Friday 06 of June 2014 17:41:22 Jesús Pérez wrote:
> > > > If you need to have access to item's parent collection attributes, you
> > > > need to retrieve the collection manually.
> > > 
> > > So I need to use a CollectionFetchJob?
> > 
> > Yes. The good things is that you don't need to return the item directly
> > in retrieveItem() method, but you can do it asynchronously, so you can
> > have something like
> 
> Hi, Daniel.
> 
> Thank you for spending your time providing me with such a detailed response.
> 
> I finally achieved my goal, thanks to your advice.
> 
> But I had to adjust your solution a little, just for the record:
> > CollectionFetchJob *fetchJob = new
> > CollectionFetchJob(Collection(item.parentCollectionId()));
> I found no such Akonadi::Item::parentCollectionId() method. I guess
> you mean item.parentCollection().id(), don't you?
> 
> Anyway, when called from retrieveItems, item.parentCollection().id()
> returns the actual collection id. But when called from retrieveItem,
> item.parentCollection().id() returns a wrong negative integer.
> I finally found that this can be fixed by calling
> changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::Pare
> nt) in resource constructor.

Yes, that's correct. Sorry, I just wrote it from top of my head and didn't 
test it at all.

> 
> Then I found that, although I get the right collection id and fetch
> job runs with no errors, I got no collections. Using the
> CollectionFetchJob constructor that receives a list of Collection::Id
> as parameter instead worked better. I.e., I replaced
> 
> new CollectionFetchJob(Collection(item.parentCollectionId()))
> 
> with
> 
> new CollectionFetchJob(QList<Collection::Id>() <<
> item.parentCollection().id())
> 
> I don't know why, I think that both should work.

Ooops, my mistake. CollectionFetchJob(const Collection &) implicitly fetches 
only subcollections of the specified collection. To fetch the specified 
collection, you need to pass second argument:

CollectionFetchJob(Collection(item.parentCollection().id()), Base)

(see CollectionFetchJob::Type)

> 
> Finally, here's a working implementation:
> http://anongit.chuso.net/testresource/tree/testresource.cpp?id=667a874#n60
> Yes, I know I should check return values and all, this is just a quick
> proof of concept, not the actual project ;-)
> 
> Now, I can store an array of collection_ids -> attribute_value in a
> private attribute in resource class so I don't have to refetch
> collection for every item since these values never change.
> 
> Now, one consideration: may I be doing the wrong choice? Wouldn't it
> be better to store this value in remoteId?
> I mean: this value never changes and needs to be read every time
> retrieveItem is called since it stores whose backend module this item
> belongs to. Wouldn't it be easier and give better performance to do
> something like this thus avoiding both changing fetch scopes and
> invoking fetch jobs?

Yes, the best approach probably would be to encode the module ownership to 
each Item's remoteID, like in the code you wrote below.

> 
> void testResource::retrieveCollections()
> {
>   Collection c1;
>   c1.setRemoteId(module_name);
>   // Do stuff
>   collectionsRetrieved( Collection::List() << c1 << ... << cn );
> }
> 
> void testResource::retrieveItems( const Akonadi::Collection &collection )
> {
>   QString module = collection.remoteId();
>   foreach( const QString &id, get_ids_from_backend( module ) ) {
>     Item item( QLatin1String( "text/directory" ) );
>     item.setRemoteId( id + "@" + module );
> 
>     items << item;
>   }
> 
>   itemsRetrieved( items );
> }
> 
> bool testResource::retrieveItem( const Akonadi::Item &item, const
> QSet<QByteArray> &parts )
> {
>   QString module = item.remoteId().replace(QRegExp(".*@"), "");
>   QString remoteId = item.remoteId().replace(QRegExp("@.*"), "");
> 
>   SomeClass payload = get_payload_from_backend(module, remoteId);
>   // Do stuff...
> 
>   itemRetrieved( newItem );
> }
> _______________________________________________
> KDE PIM mailing list kde-pim at kde.org
> https://mail.kde.org/mailman/listinfo/kde-pim
> KDE PIM home page at http://pim.kde.org/

-- 
Daniel Vrátil | dvratil at redhat.com | dvratil on #kde-devel, #kontact, #akonadi
KDE Desktop Team
Associate Software Engineer, Red Hat

GPG Key: 0xC59D614F6F4AE348
Fingerprint: 4EC1 86E3 C54E 0B39 5FDD B5FB C59D 614F 6F4A E348
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.kde.org/pipermail/kde-pim/attachments/20140609/81f7b023/attachment.sig>
-------------- next part --------------
_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/


More information about the kde-pim mailing list