[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