<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.meego.com/skins/common/feed.css?270"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.meego.com/index.php?title=Special:Contributions/Murrayc&amp;feed=atom&amp;limit=50&amp;target=Murrayc&amp;year=&amp;month=</id>
		<title>MeeGo wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.meego.com/index.php?title=Special:Contributions/Murrayc&amp;feed=atom&amp;limit=50&amp;target=Murrayc&amp;year=&amp;month="/>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Special:Contributions/Murrayc"/>
		<updated>2013-05-21T15:46:25Z</updated>
		<subtitle>From MeeGo wiki</subtitle>
		<generator>MediaWiki 1.16.2</generator>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-10-06T06:53:24Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* More Efficient Access to Meta Data for Change Tracking */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
See the list of [https://bugzilla.gnome.org/buglist.cgi?status_whiteboard_type=allwordssubstr;query_format=advanced;field0-0-0=product;status_whiteboard=meego;bug_status=UNCONFIRMED;bug_status=NEW;bug_status=ASSIGNED;bug_status=REOPENED;bug_status=NEEDINFO;type0-0-0=substring;value0-0-0=Evolution-Data-Server &amp;quot;meego&amp;quot; bugs in the upstream evolution-data-server bugzilla].&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Notify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug] (DONE)&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652179 libebook: Upstream evolution-data-server bug] (DONE)&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652180 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html]&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-10-06T06:50:50Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Notify with UIDs Only */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
See the list of [https://bugzilla.gnome.org/buglist.cgi?status_whiteboard_type=allwordssubstr;query_format=advanced;field0-0-0=product;status_whiteboard=meego;bug_status=UNCONFIRMED;bug_status=NEW;bug_status=ASSIGNED;bug_status=REOPENED;bug_status=NEEDINFO;type0-0-0=substring;value0-0-0=Evolution-Data-Server &amp;quot;meego&amp;quot; bugs in the upstream evolution-data-server bugzilla].&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Notify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug] (DONE)&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652179 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652180 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html]&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Maliit</id>
		<title>Maliit</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Maliit"/>
				<updated>2011-06-16T08:17:08Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Rewrite introductory sentence.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Maliit]][[Category:MeeGo Input Methods]]&lt;br /&gt;
{{MaliitNavigationBar}}&lt;br /&gt;
&lt;br /&gt;
[[File:Maliit2.png|448px|link=]]&lt;br /&gt;
&lt;br /&gt;
Maliit provides a flexible and cross-platform input method framework, including a virtual keyboard. It works on all MeeGo user experiences, and in other GNU/Linux distributions.&lt;br /&gt;
&lt;br /&gt;
== Goals ==&lt;br /&gt;
&lt;br /&gt;
Maliit aims to be ''the'' input method project for MeeGo and other GNU/Linux-based embedded/mobile platforms. To achieve this we should provide:&lt;br /&gt;
&lt;br /&gt;
'''A solid input method framework'''&lt;br /&gt;
&lt;br /&gt;
This includes support for traditional input methods such as hardware and virtual keyboards. More exotic input methods should also be possible, such as handwriting recognition and voice input, and special purpose input methods such as date/time pickers, tag clouds, etc.&lt;br /&gt;
&lt;br /&gt;
'''A core set of input methods'''&lt;br /&gt;
&lt;br /&gt;
The default set of input methods should demonstrate the core capabilities of the framework and provide a good user experience that device manufacturers and integrators can use easily.&lt;br /&gt;
&lt;br /&gt;
We also aim to:&lt;br /&gt;
&lt;br /&gt;
'''Empower third-party developers'''&lt;br /&gt;
&lt;br /&gt;
Customizing existing input methods or developing powerful new input methods should be simple, regardless of whether it is for profit, research or fun.&lt;br /&gt;
&lt;br /&gt;
'''Build a diverse community of contributors'''&lt;br /&gt;
&lt;br /&gt;
Employees from different companies, freelancers, members of academia, hackers and volunteers should all be welcomed and encouraged to contribute to the project.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
=== For end users ===&lt;br /&gt;
Following are the high level end-user features supported by Maliit:&lt;br /&gt;
&lt;br /&gt;
* Multitouch virtual keyboard&lt;br /&gt;
** Landscape and portrait QWERTY with dedicated symbol views&lt;br /&gt;
** Support for multiple languages and scripts (e.g. latin, cyrillic, arabic, chinese)&lt;br /&gt;
*** See current layouts at [http://meego.gitorious.org/meegotouch/meegotouch-inputmethodkeyboard/trees/master/m-keyboard/layouts MeeGo gitorius]&lt;br /&gt;
** Number/phone number layouts for entering numbers/phone numbers&lt;br /&gt;
* Context sensitive and dynamic action key&lt;br /&gt;
** e.g. replacing enter icon with search icon and highlighting the key in search fields - and respective search key inactive when search field empty&lt;br /&gt;
* Context sensitive layouts&lt;br /&gt;
** e.g. replacing ',' key with '@' in e-mail address fields&lt;br /&gt;
* Simple interactions (as defined in [http://meego.com/developers/ui-design-guidelines/handset/meego-basics MeeGo Basics])&lt;br /&gt;
** Swipe sideways to easily switch between different active keyboard layouts and other input methods&lt;br /&gt;
** Swipe down to close virtual keyboard or alternatively tap outiside the active input area to close keyboard&lt;br /&gt;
* Low-latency haptics typing feedback (with feedback framework backend); sound,tactile&lt;br /&gt;
&lt;br /&gt;
[[File:Text-input-1.png|Virtual keyboard interaction : opening and closing the keyboard]]&lt;br /&gt;
&lt;br /&gt;
* Cut/Copy/Paste for text input&lt;br /&gt;
** Separate text editor widget for text input fields&lt;br /&gt;
* Error correction / word prediction for virtual keyboard (with error correction / prediction engine)&lt;br /&gt;
** Separate widget for correction/prediction candidates&lt;br /&gt;
* Hardware keyboard&lt;br /&gt;
** Long pressing of keys either to autorepeat (e.g. arrow keys, backspace) or to input secondary characters (e.g. numbers, symbols)&lt;br /&gt;
** Possibility to extend hardware keys with virtual keys (e.g. for additional symbols)&lt;br /&gt;
&lt;br /&gt;
[[File:Text-input-2a.png|Text input with hardware keyboard]]&lt;br /&gt;
&lt;br /&gt;
* Toolbar for appliction specific input content&lt;br /&gt;
** For placing buttons, labels etc.&lt;br /&gt;
** Toolbar located on top of virtual keyboard, with hardware keyboard in the bottom of the screen&lt;br /&gt;
&lt;br /&gt;
[[File:Confirming.png|Placing application specific actions in the input toolbar, when application UI is not visible or &amp;quot;Enter&amp;quot; action is not adequate]]&lt;br /&gt;
&lt;br /&gt;
* External input methods&lt;br /&gt;
** e.g. Bluetooth keyboards&lt;br /&gt;
&lt;br /&gt;
=== For integrators and developers ===&lt;br /&gt;
* Input Methods can be implemented as plugins&lt;br /&gt;
* Error correction/prediction engines can be implemented as plugins&lt;br /&gt;
* Framework is licensed LGPL&lt;br /&gt;
* Keyboard has theming abilities via CSS file&lt;br /&gt;
* Meego Keyboard has customizable layout files&lt;br /&gt;
* Meego Feedback framework has swappable backends (for haptics et.c.)&lt;br /&gt;
* Support for additional toolkits can be done by using the DBus connection for the Input Context&lt;br /&gt;
&lt;br /&gt;
== Maliit in action ==&lt;br /&gt;
&lt;br /&gt;
Maliit is used on a number of devices and form factors, and can easily be adapted to run on new ones.&lt;br /&gt;
&lt;br /&gt;
* [http://www.linpus.com/products_meego_slate.html Linpus Slate] ([http://www.linpus.com/images/slate/kb.png screenshot showing Linpus virtual keyboard])&lt;br /&gt;
* [http://appdeveloper.intel.com/en-us/meego-iso-esla Intel MeeGo Tablet] ([http://www.engadget.com/photos/new-meego-tablet-user-experience-hands-on-at-mwc-2011/#3877322 pictures showing Swype keyboard])&lt;br /&gt;
* [http://www.youtube.com/watch?v=l_7f3Lxd4_I GNOME3 on a WeTab (video)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;250px&amp;quot; heights=&amp;quot;250px&amp;quot; perrow=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
Image:Lenovo_meego_vkb.jpg| [[Maliit/MeeGo 1.1#Netbook|MeeGo 1.1 Netbook]] with MeeGo Keyboard on Lenovo S10-3T Ideapad&lt;br /&gt;
Image:Meego1.1_handset_on_aava.jpg| [http://meego.com/downloads/releases/1.1/meego-v1.1-handset MeeGo 1.1 Handset] with MeeGo Keyboard on Aava Mobile&lt;br /&gt;
Image:tegra-vkb2.jpg| MeeGo 1.2 prerelease on [[ARM/TEGRA2|Advent Vega, Tegra2]]&lt;br /&gt;
Image:Maliit-on-lucid.png | Ubuntu Lucid (10.04)&lt;br /&gt;
Image:Maliit-in-GNOME3.jpg | GNOME3 on a WeTab&lt;br /&gt;
Image:Maliit-on-KDE-Plasma.jpg | KDE, using Plasma&lt;br /&gt;
[[File:TransparentPlaceholder.png|link=http://wikipedia.org|caption]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Communication channels ==&lt;br /&gt;
&lt;br /&gt;
'''Mailing list:''' meego-inputmethods@lists.meego.com  ([http://lists.meego.com/listinfo/meego-inputmethods listinfo] | [http://lists.meego.com/pipermail/meego-inputmethods/ archives])&lt;br /&gt;
&lt;br /&gt;
'''Bugtracker:''' bugs.meego.com, Product: OS, Component: Virtual Keyboard ([https://bugs.meego.com/buglist.cgi?classification=MeeGo%20Platform&amp;amp;query_based_on=virtual%20keyboard&amp;amp;query_format=advanced&amp;amp;bug_status=NEW&amp;amp;bug_status=NEEDINFO&amp;amp;bug_status=INDEFINITION&amp;amp;bug_status=ASSIGNED&amp;amp;bug_status=ACCEPTED&amp;amp;bug_status=WAITING%20FOR%20UPSTREAM&amp;amp;bug_status=WAITING&amp;amp;bug_status=REOPENED&amp;amp;component=Virtual%20keyboard&amp;amp;product=OS%20Base&amp;amp;known_name=virtual%20keyboard open bugs] | &lt;br /&gt;
[https://bugs.meego.com/enter_bug.cgi?product=OS%20Base&amp;amp;component=Virtual%20keyboard file new bug])&lt;br /&gt;
&lt;br /&gt;
'''IRC:''' Visit us in #meego-inputmethods at freenode.net ([http://webchat.freenode.net/?randomnick=1&amp;amp;channels=meego-inputmethods&amp;amp;uio=d4 webchat])&lt;br /&gt;
&lt;br /&gt;
== News ==&lt;br /&gt;
* 07.06.2011 - Session at MeeGo Spring Conference 2011. [http://sf2011.meego.com/program/sessions/developing-custom-input-methods-meego Info, Recording]&lt;br /&gt;
* 08.04.2011 - MeeGo Keyboard is relicensed with BSD license: [http://lists.meego.com/pipermail/meego-dev/2011-April/482578.html Announcement]&lt;br /&gt;
* 29.03.2011 - Held first offical IRC meeting: [[Maliit/Meetings|How can we simplify development and maintenance of input contexts?]]&lt;br /&gt;
* 04.03.2011 - API/ABI break in 0.20.0: [http://lists.meego.com/pipermail/meego-dev/2011-March/481869.html meego-im-framework is removing dependency to libmeegotouch from its API]&lt;br /&gt;
* 23.02.2011 - Packages available for Ubuntu Lucid/Maverick to ease development. [http://taschenorakel.de/michael/2011/02/24/meego-input-methods-your-desktop/ Blogpost], [[#Packages for Ubuntu .2810.04 Lucid Lynx .2F 10.10 Maveric Meerkat.29|documentation]]&lt;br /&gt;
* 17.02.2011 - Claudio Saavedra started on MeeGo+Gtk integration work, focusing on input methods. [http://people.gnome.org/~csaavedra/news-2011-02.html#D10 Blogpost]&lt;br /&gt;
* 13.02.2011 - MeeGo Tablet UX demoed at Mobile World Conference, with Swype keyboard. [http://www.engadget.com/photos/new-meego-tablet-user-experience-hands-on-at-mwc-2011/#3877322 Pictures]&lt;br /&gt;
* 01.02.2011 - API/ABI break in 0.19.41: [http://lists.meego.com/pipermail/meego-dev/2011-February/481353.html meegoimframework interfaces related to orientation change will be changed]&lt;br /&gt;
* 15.11.2010 - Architect and Lead Developer of Maliit give talk at MeeGo Conference. [http://conference2010.meego.com/session/meego-touch-input-method-frameworks Info, Recording]&lt;br /&gt;
* 15.11.2010 - Linpus shows off MeeGo based slate at MeeGo Conference, with keyboard based on Maliit. &lt;br /&gt;
* 30.06.2010 - MeeGo Handset UX Day 1 release, first public release of MeeGo Input Methods. [http://meego.com/community/blogs/valhalla/2010/meego-handset-project-day-1-here Announcement]&lt;br /&gt;
&lt;br /&gt;
== Roadmap ==&lt;br /&gt;
See [[Maliit/Roadmap]]&lt;br /&gt;
&lt;br /&gt;
== Upcoming events ==&lt;br /&gt;
* June 24th, MeeGo Freeday workshop, details TBA.&lt;br /&gt;
* August 6th-12th - Desktop Summit Berlin.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
See [[Maliit/Ideas]]&lt;br /&gt;
&lt;br /&gt;
== Developers ==&lt;br /&gt;
See [[Maliit/Development]]&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
See [[Maliit/Documentation]]&lt;br /&gt;
&lt;br /&gt;
{{MaliitNavigationBar}}&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Maliit</id>
		<title>Maliit</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Maliit"/>
				<updated>2011-06-16T08:14:27Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Goals: Slight rewrite, though I think the overview needs to be more visual in general.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Maliit]][[Category:MeeGo Input Methods]]&lt;br /&gt;
{{MaliitNavigationBar}}&lt;br /&gt;
&lt;br /&gt;
[[File:Maliit2.png|448px|link=]]&lt;br /&gt;
&lt;br /&gt;
Maliit provides a flexible and cross platform input method framework. It is usable on all MeeGo user experiences, and in other GNU/Linux distributions as well.&lt;br /&gt;
&lt;br /&gt;
== Goals ==&lt;br /&gt;
&lt;br /&gt;
Maliit aims to be ''the'' input method project for MeeGo and other GNU/Linux-based embedded/mobile platforms. To achieve this we should provide:&lt;br /&gt;
&lt;br /&gt;
'''A solid input method framework'''&lt;br /&gt;
&lt;br /&gt;
This includes support for traditional input methods such as hardware and virtual keyboards. More exotic input methods should also be possible, such as handwriting recognition and voice input, and special purpose input methods such as date/time pickers, tag clouds, etc.&lt;br /&gt;
&lt;br /&gt;
'''A core set of input methods'''&lt;br /&gt;
&lt;br /&gt;
The default set of input methods should demonstrate the core capabilities of the framework and provide a good user experience that device manufacturers and integrators can use easily.&lt;br /&gt;
&lt;br /&gt;
We also aim to:&lt;br /&gt;
&lt;br /&gt;
'''Empower third-party developers'''&lt;br /&gt;
&lt;br /&gt;
Customizing existing input methods or developing powerful new input methods should be simple, regardless of whether it is for profit, research or fun.&lt;br /&gt;
&lt;br /&gt;
'''Build a diverse community of contributors'''&lt;br /&gt;
&lt;br /&gt;
Employees from different companies, freelancers, members of academia, hackers and volunteers should all be welcomed and encouraged to contribute to the project.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
=== For end users ===&lt;br /&gt;
Following are the high level end-user features supported by Maliit:&lt;br /&gt;
&lt;br /&gt;
* Multitouch virtual keyboard&lt;br /&gt;
** Landscape and portrait QWERTY with dedicated symbol views&lt;br /&gt;
** Support for multiple languages and scripts (e.g. latin, cyrillic, arabic, chinese)&lt;br /&gt;
*** See current layouts at [http://meego.gitorious.org/meegotouch/meegotouch-inputmethodkeyboard/trees/master/m-keyboard/layouts MeeGo gitorius]&lt;br /&gt;
** Number/phone number layouts for entering numbers/phone numbers&lt;br /&gt;
* Context sensitive and dynamic action key&lt;br /&gt;
** e.g. replacing enter icon with search icon and highlighting the key in search fields - and respective search key inactive when search field empty&lt;br /&gt;
* Context sensitive layouts&lt;br /&gt;
** e.g. replacing ',' key with '@' in e-mail address fields&lt;br /&gt;
* Simple interactions (as defined in [http://meego.com/developers/ui-design-guidelines/handset/meego-basics MeeGo Basics])&lt;br /&gt;
** Swipe sideways to easily switch between different active keyboard layouts and other input methods&lt;br /&gt;
** Swipe down to close virtual keyboard or alternatively tap outiside the active input area to close keyboard&lt;br /&gt;
* Low-latency haptics typing feedback (with feedback framework backend); sound,tactile&lt;br /&gt;
&lt;br /&gt;
[[File:Text-input-1.png|Virtual keyboard interaction : opening and closing the keyboard]]&lt;br /&gt;
&lt;br /&gt;
* Cut/Copy/Paste for text input&lt;br /&gt;
** Separate text editor widget for text input fields&lt;br /&gt;
* Error correction / word prediction for virtual keyboard (with error correction / prediction engine)&lt;br /&gt;
** Separate widget for correction/prediction candidates&lt;br /&gt;
* Hardware keyboard&lt;br /&gt;
** Long pressing of keys either to autorepeat (e.g. arrow keys, backspace) or to input secondary characters (e.g. numbers, symbols)&lt;br /&gt;
** Possibility to extend hardware keys with virtual keys (e.g. for additional symbols)&lt;br /&gt;
&lt;br /&gt;
[[File:Text-input-2a.png|Text input with hardware keyboard]]&lt;br /&gt;
&lt;br /&gt;
* Toolbar for appliction specific input content&lt;br /&gt;
** For placing buttons, labels etc.&lt;br /&gt;
** Toolbar located on top of virtual keyboard, with hardware keyboard in the bottom of the screen&lt;br /&gt;
&lt;br /&gt;
[[File:Confirming.png|Placing application specific actions in the input toolbar, when application UI is not visible or &amp;quot;Enter&amp;quot; action is not adequate]]&lt;br /&gt;
&lt;br /&gt;
* External input methods&lt;br /&gt;
** e.g. Bluetooth keyboards&lt;br /&gt;
&lt;br /&gt;
=== For integrators and developers ===&lt;br /&gt;
* Input Methods can be implemented as plugins&lt;br /&gt;
* Error correction/prediction engines can be implemented as plugins&lt;br /&gt;
* Framework is licensed LGPL&lt;br /&gt;
* Keyboard has theming abilities via CSS file&lt;br /&gt;
* Meego Keyboard has customizable layout files&lt;br /&gt;
* Meego Feedback framework has swappable backends (for haptics et.c.)&lt;br /&gt;
* Support for additional toolkits can be done by using the DBus connection for the Input Context&lt;br /&gt;
&lt;br /&gt;
== Maliit in action ==&lt;br /&gt;
&lt;br /&gt;
Maliit is used on a number of devices and form factors, and can easily be adapted to run on new ones.&lt;br /&gt;
&lt;br /&gt;
* [http://www.linpus.com/products_meego_slate.html Linpus Slate] ([http://www.linpus.com/images/slate/kb.png screenshot showing Linpus virtual keyboard])&lt;br /&gt;
* [http://appdeveloper.intel.com/en-us/meego-iso-esla Intel MeeGo Tablet] ([http://www.engadget.com/photos/new-meego-tablet-user-experience-hands-on-at-mwc-2011/#3877322 pictures showing Swype keyboard])&lt;br /&gt;
* [http://www.youtube.com/watch?v=l_7f3Lxd4_I GNOME3 on a WeTab (video)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;250px&amp;quot; heights=&amp;quot;250px&amp;quot; perrow=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
Image:Lenovo_meego_vkb.jpg| [[Maliit/MeeGo 1.1#Netbook|MeeGo 1.1 Netbook]] with MeeGo Keyboard on Lenovo S10-3T Ideapad&lt;br /&gt;
Image:Meego1.1_handset_on_aava.jpg| [http://meego.com/downloads/releases/1.1/meego-v1.1-handset MeeGo 1.1 Handset] with MeeGo Keyboard on Aava Mobile&lt;br /&gt;
Image:tegra-vkb2.jpg| MeeGo 1.2 prerelease on [[ARM/TEGRA2|Advent Vega, Tegra2]]&lt;br /&gt;
Image:Maliit-on-lucid.png | Ubuntu Lucid (10.04)&lt;br /&gt;
Image:Maliit-in-GNOME3.jpg | GNOME3 on a WeTab&lt;br /&gt;
Image:Maliit-on-KDE-Plasma.jpg | KDE, using Plasma&lt;br /&gt;
[[File:TransparentPlaceholder.png|link=http://wikipedia.org|caption]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Communication channels ==&lt;br /&gt;
&lt;br /&gt;
'''Mailing list:''' meego-inputmethods@lists.meego.com  ([http://lists.meego.com/listinfo/meego-inputmethods listinfo] | [http://lists.meego.com/pipermail/meego-inputmethods/ archives])&lt;br /&gt;
&lt;br /&gt;
'''Bugtracker:''' bugs.meego.com, Product: OS, Component: Virtual Keyboard ([https://bugs.meego.com/buglist.cgi?classification=MeeGo%20Platform&amp;amp;query_based_on=virtual%20keyboard&amp;amp;query_format=advanced&amp;amp;bug_status=NEW&amp;amp;bug_status=NEEDINFO&amp;amp;bug_status=INDEFINITION&amp;amp;bug_status=ASSIGNED&amp;amp;bug_status=ACCEPTED&amp;amp;bug_status=WAITING%20FOR%20UPSTREAM&amp;amp;bug_status=WAITING&amp;amp;bug_status=REOPENED&amp;amp;component=Virtual%20keyboard&amp;amp;product=OS%20Base&amp;amp;known_name=virtual%20keyboard open bugs] | &lt;br /&gt;
[https://bugs.meego.com/enter_bug.cgi?product=OS%20Base&amp;amp;component=Virtual%20keyboard file new bug])&lt;br /&gt;
&lt;br /&gt;
'''IRC:''' Visit us in #meego-inputmethods at freenode.net ([http://webchat.freenode.net/?randomnick=1&amp;amp;channels=meego-inputmethods&amp;amp;uio=d4 webchat])&lt;br /&gt;
&lt;br /&gt;
== News ==&lt;br /&gt;
* 07.06.2011 - Session at MeeGo Spring Conference 2011. [http://sf2011.meego.com/program/sessions/developing-custom-input-methods-meego Info, Recording]&lt;br /&gt;
* 08.04.2011 - MeeGo Keyboard is relicensed with BSD license: [http://lists.meego.com/pipermail/meego-dev/2011-April/482578.html Announcement]&lt;br /&gt;
* 29.03.2011 - Held first offical IRC meeting: [[Maliit/Meetings|How can we simplify development and maintenance of input contexts?]]&lt;br /&gt;
* 04.03.2011 - API/ABI break in 0.20.0: [http://lists.meego.com/pipermail/meego-dev/2011-March/481869.html meego-im-framework is removing dependency to libmeegotouch from its API]&lt;br /&gt;
* 23.02.2011 - Packages available for Ubuntu Lucid/Maverick to ease development. [http://taschenorakel.de/michael/2011/02/24/meego-input-methods-your-desktop/ Blogpost], [[#Packages for Ubuntu .2810.04 Lucid Lynx .2F 10.10 Maveric Meerkat.29|documentation]]&lt;br /&gt;
* 17.02.2011 - Claudio Saavedra started on MeeGo+Gtk integration work, focusing on input methods. [http://people.gnome.org/~csaavedra/news-2011-02.html#D10 Blogpost]&lt;br /&gt;
* 13.02.2011 - MeeGo Tablet UX demoed at Mobile World Conference, with Swype keyboard. [http://www.engadget.com/photos/new-meego-tablet-user-experience-hands-on-at-mwc-2011/#3877322 Pictures]&lt;br /&gt;
* 01.02.2011 - API/ABI break in 0.19.41: [http://lists.meego.com/pipermail/meego-dev/2011-February/481353.html meegoimframework interfaces related to orientation change will be changed]&lt;br /&gt;
* 15.11.2010 - Architect and Lead Developer of Maliit give talk at MeeGo Conference. [http://conference2010.meego.com/session/meego-touch-input-method-frameworks Info, Recording]&lt;br /&gt;
* 15.11.2010 - Linpus shows off MeeGo based slate at MeeGo Conference, with keyboard based on Maliit. &lt;br /&gt;
* 30.06.2010 - MeeGo Handset UX Day 1 release, first public release of MeeGo Input Methods. [http://meego.com/community/blogs/valhalla/2010/meego-handset-project-day-1-here Announcement]&lt;br /&gt;
&lt;br /&gt;
== Roadmap ==&lt;br /&gt;
See [[Maliit/Roadmap]]&lt;br /&gt;
&lt;br /&gt;
== Upcoming events ==&lt;br /&gt;
* June 24th, MeeGo Freeday workshop, details TBA.&lt;br /&gt;
* August 6th-12th - Desktop Summit Berlin.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
See [[Maliit/Ideas]]&lt;br /&gt;
&lt;br /&gt;
== Developers ==&lt;br /&gt;
See [[Maliit/Development]]&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
See [[Maliit/Documentation]]&lt;br /&gt;
&lt;br /&gt;
{{MaliitNavigationBar}}&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Maliit</id>
		<title>Maliit</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Maliit"/>
				<updated>2011-06-16T08:09:15Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Move actual overview text to the top of the overview&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Maliit]][[Category:MeeGo Input Methods]]&lt;br /&gt;
{{MaliitNavigationBar}}&lt;br /&gt;
&lt;br /&gt;
[[File:Maliit2.png|448px|link=]]&lt;br /&gt;
&lt;br /&gt;
Maliit provides a flexible and cross platform input method framework. It is usable on all MeeGo user experiences, and in other GNU/Linux distributions as well.&lt;br /&gt;
&lt;br /&gt;
== Goals ==&lt;br /&gt;
&lt;br /&gt;
The overall goal of Maliit is to be ''the'' input method project for MeeGo and other GNU/Linux-based embedded/mobile platforms. To achieve this we aim to:&lt;br /&gt;
&lt;br /&gt;
'''Provide a solid input method framework'''&lt;br /&gt;
&lt;br /&gt;
This includes explicit support for traditional input methods like hardware and virtual keyboards. More exotic input methods like handwriting recognition and voice input, and special purpose input methods like date/time pickers, tag clouds, et.c. should also be possible.&lt;br /&gt;
&lt;br /&gt;
'''Provide a core set of input methods'''&lt;br /&gt;
&lt;br /&gt;
The default set of input methods should demonstrate the core capabilites of the framework, and provide a good user experience that device manufacturers and integrators can use with little to no adaptation.&lt;br /&gt;
&lt;br /&gt;
'''Empower third-party developers'''&lt;br /&gt;
&lt;br /&gt;
Customizing existing or developing powerful new input methods should be simple, regardless of whether it is for profit, research or fun.&lt;br /&gt;
&lt;br /&gt;
'''Have a diverse community of contributors'''&lt;br /&gt;
&lt;br /&gt;
Employees from different companies, freelancers, members of academia, hackers and volunteers should all be welcomed and encouraged to contribute to the project.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
&lt;br /&gt;
=== For end users ===&lt;br /&gt;
Following are the high level end-user features supported by Maliit:&lt;br /&gt;
&lt;br /&gt;
* Multitouch virtual keyboard&lt;br /&gt;
** Landscape and portrait QWERTY with dedicated symbol views&lt;br /&gt;
** Support for multiple languages and scripts (e.g. latin, cyrillic, arabic, chinese)&lt;br /&gt;
*** See current layouts at [http://meego.gitorious.org/meegotouch/meegotouch-inputmethodkeyboard/trees/master/m-keyboard/layouts MeeGo gitorius]&lt;br /&gt;
** Number/phone number layouts for entering numbers/phone numbers&lt;br /&gt;
* Context sensitive and dynamic action key&lt;br /&gt;
** e.g. replacing enter icon with search icon and highlighting the key in search fields - and respective search key inactive when search field empty&lt;br /&gt;
* Context sensitive layouts&lt;br /&gt;
** e.g. replacing ',' key with '@' in e-mail address fields&lt;br /&gt;
* Simple interactions (as defined in [http://meego.com/developers/ui-design-guidelines/handset/meego-basics MeeGo Basics])&lt;br /&gt;
** Swipe sideways to easily switch between different active keyboard layouts and other input methods&lt;br /&gt;
** Swipe down to close virtual keyboard or alternatively tap outiside the active input area to close keyboard&lt;br /&gt;
* Low-latency haptics typing feedback (with feedback framework backend); sound,tactile&lt;br /&gt;
&lt;br /&gt;
[[File:Text-input-1.png|Virtual keyboard interaction : opening and closing the keyboard]]&lt;br /&gt;
&lt;br /&gt;
* Cut/Copy/Paste for text input&lt;br /&gt;
** Separate text editor widget for text input fields&lt;br /&gt;
* Error correction / word prediction for virtual keyboard (with error correction / prediction engine)&lt;br /&gt;
** Separate widget for correction/prediction candidates&lt;br /&gt;
* Hardware keyboard&lt;br /&gt;
** Long pressing of keys either to autorepeat (e.g. arrow keys, backspace) or to input secondary characters (e.g. numbers, symbols)&lt;br /&gt;
** Possibility to extend hardware keys with virtual keys (e.g. for additional symbols)&lt;br /&gt;
&lt;br /&gt;
[[File:Text-input-2a.png|Text input with hardware keyboard]]&lt;br /&gt;
&lt;br /&gt;
* Toolbar for appliction specific input content&lt;br /&gt;
** For placing buttons, labels etc.&lt;br /&gt;
** Toolbar located on top of virtual keyboard, with hardware keyboard in the bottom of the screen&lt;br /&gt;
&lt;br /&gt;
[[File:Confirming.png|Placing application specific actions in the input toolbar, when application UI is not visible or &amp;quot;Enter&amp;quot; action is not adequate]]&lt;br /&gt;
&lt;br /&gt;
* External input methods&lt;br /&gt;
** e.g. Bluetooth keyboards&lt;br /&gt;
&lt;br /&gt;
=== For integrators and developers ===&lt;br /&gt;
* Input Methods can be implemented as plugins&lt;br /&gt;
* Error correction/prediction engines can be implemented as plugins&lt;br /&gt;
* Framework is licensed LGPL&lt;br /&gt;
* Keyboard has theming abilities via CSS file&lt;br /&gt;
* Meego Keyboard has customizable layout files&lt;br /&gt;
* Meego Feedback framework has swappable backends (for haptics et.c.)&lt;br /&gt;
* Support for additional toolkits can be done by using the DBus connection for the Input Context&lt;br /&gt;
&lt;br /&gt;
== Maliit in action ==&lt;br /&gt;
&lt;br /&gt;
Maliit is used on a number of devices and form factors, and can easily be adapted to run on new ones.&lt;br /&gt;
&lt;br /&gt;
* [http://www.linpus.com/products_meego_slate.html Linpus Slate] ([http://www.linpus.com/images/slate/kb.png screenshot showing Linpus virtual keyboard])&lt;br /&gt;
* [http://appdeveloper.intel.com/en-us/meego-iso-esla Intel MeeGo Tablet] ([http://www.engadget.com/photos/new-meego-tablet-user-experience-hands-on-at-mwc-2011/#3877322 pictures showing Swype keyboard])&lt;br /&gt;
* [http://www.youtube.com/watch?v=l_7f3Lxd4_I GNOME3 on a WeTab (video)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;250px&amp;quot; heights=&amp;quot;250px&amp;quot; perrow=&amp;quot;3&amp;quot;&amp;gt;&lt;br /&gt;
Image:Lenovo_meego_vkb.jpg| [[Maliit/MeeGo 1.1#Netbook|MeeGo 1.1 Netbook]] with MeeGo Keyboard on Lenovo S10-3T Ideapad&lt;br /&gt;
Image:Meego1.1_handset_on_aava.jpg| [http://meego.com/downloads/releases/1.1/meego-v1.1-handset MeeGo 1.1 Handset] with MeeGo Keyboard on Aava Mobile&lt;br /&gt;
Image:tegra-vkb2.jpg| MeeGo 1.2 prerelease on [[ARM/TEGRA2|Advent Vega, Tegra2]]&lt;br /&gt;
Image:Maliit-on-lucid.png | Ubuntu Lucid (10.04)&lt;br /&gt;
Image:Maliit-in-GNOME3.jpg | GNOME3 on a WeTab&lt;br /&gt;
Image:Maliit-on-KDE-Plasma.jpg | KDE, using Plasma&lt;br /&gt;
[[File:TransparentPlaceholder.png|link=http://wikipedia.org|caption]]&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Communication channels ==&lt;br /&gt;
&lt;br /&gt;
'''Mailing list:''' meego-inputmethods@lists.meego.com  ([http://lists.meego.com/listinfo/meego-inputmethods listinfo] | [http://lists.meego.com/pipermail/meego-inputmethods/ archives])&lt;br /&gt;
&lt;br /&gt;
'''Bugtracker:''' bugs.meego.com, Product: OS, Component: Virtual Keyboard ([https://bugs.meego.com/buglist.cgi?classification=MeeGo%20Platform&amp;amp;query_based_on=virtual%20keyboard&amp;amp;query_format=advanced&amp;amp;bug_status=NEW&amp;amp;bug_status=NEEDINFO&amp;amp;bug_status=INDEFINITION&amp;amp;bug_status=ASSIGNED&amp;amp;bug_status=ACCEPTED&amp;amp;bug_status=WAITING%20FOR%20UPSTREAM&amp;amp;bug_status=WAITING&amp;amp;bug_status=REOPENED&amp;amp;component=Virtual%20keyboard&amp;amp;product=OS%20Base&amp;amp;known_name=virtual%20keyboard open bugs] | &lt;br /&gt;
[https://bugs.meego.com/enter_bug.cgi?product=OS%20Base&amp;amp;component=Virtual%20keyboard file new bug])&lt;br /&gt;
&lt;br /&gt;
'''IRC:''' Visit us in #meego-inputmethods at freenode.net ([http://webchat.freenode.net/?randomnick=1&amp;amp;channels=meego-inputmethods&amp;amp;uio=d4 webchat])&lt;br /&gt;
&lt;br /&gt;
== News ==&lt;br /&gt;
* 07.06.2011 - Session at MeeGo Spring Conference 2011. [http://sf2011.meego.com/program/sessions/developing-custom-input-methods-meego Info, Recording]&lt;br /&gt;
* 08.04.2011 - MeeGo Keyboard is relicensed with BSD license: [http://lists.meego.com/pipermail/meego-dev/2011-April/482578.html Announcement]&lt;br /&gt;
* 29.03.2011 - Held first offical IRC meeting: [[Maliit/Meetings|How can we simplify development and maintenance of input contexts?]]&lt;br /&gt;
* 04.03.2011 - API/ABI break in 0.20.0: [http://lists.meego.com/pipermail/meego-dev/2011-March/481869.html meego-im-framework is removing dependency to libmeegotouch from its API]&lt;br /&gt;
* 23.02.2011 - Packages available for Ubuntu Lucid/Maverick to ease development. [http://taschenorakel.de/michael/2011/02/24/meego-input-methods-your-desktop/ Blogpost], [[#Packages for Ubuntu .2810.04 Lucid Lynx .2F 10.10 Maveric Meerkat.29|documentation]]&lt;br /&gt;
* 17.02.2011 - Claudio Saavedra started on MeeGo+Gtk integration work, focusing on input methods. [http://people.gnome.org/~csaavedra/news-2011-02.html#D10 Blogpost]&lt;br /&gt;
* 13.02.2011 - MeeGo Tablet UX demoed at Mobile World Conference, with Swype keyboard. [http://www.engadget.com/photos/new-meego-tablet-user-experience-hands-on-at-mwc-2011/#3877322 Pictures]&lt;br /&gt;
* 01.02.2011 - API/ABI break in 0.19.41: [http://lists.meego.com/pipermail/meego-dev/2011-February/481353.html meegoimframework interfaces related to orientation change will be changed]&lt;br /&gt;
* 15.11.2010 - Architect and Lead Developer of Maliit give talk at MeeGo Conference. [http://conference2010.meego.com/session/meego-touch-input-method-frameworks Info, Recording]&lt;br /&gt;
* 15.11.2010 - Linpus shows off MeeGo based slate at MeeGo Conference, with keyboard based on Maliit. &lt;br /&gt;
* 30.06.2010 - MeeGo Handset UX Day 1 release, first public release of MeeGo Input Methods. [http://meego.com/community/blogs/valhalla/2010/meego-handset-project-day-1-here Announcement]&lt;br /&gt;
&lt;br /&gt;
== Roadmap ==&lt;br /&gt;
See [[Maliit/Roadmap]]&lt;br /&gt;
&lt;br /&gt;
== Upcoming events ==&lt;br /&gt;
* June 24th, MeeGo Freeday workshop, details TBA.&lt;br /&gt;
* August 6th-12th - Desktop Summit Berlin.&lt;br /&gt;
&lt;br /&gt;
== Ideas ==&lt;br /&gt;
See [[Maliit/Ideas]]&lt;br /&gt;
&lt;br /&gt;
== Developers ==&lt;br /&gt;
See [[Maliit/Development]]&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
See [[Maliit/Documentation]]&lt;br /&gt;
&lt;br /&gt;
{{MaliitNavigationBar}}&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-14T10:38:42Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Fix typo, though this will break links to this sub-section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
See the list of [https://bugzilla.gnome.org/buglist.cgi?status_whiteboard_type=allwordssubstr;query_format=advanced;field0-0-0=product;status_whiteboard=meego;bug_status=UNCONFIRMED;bug_status=NEW;bug_status=ASSIGNED;bug_status=REOPENED;bug_status=NEEDINFO;type0-0-0=substring;value0-0-0=Evolution-Data-Server &amp;quot;meego&amp;quot; bugs in the upstream evolution-data-server bugzilla].&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Notify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652179 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652180 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html]&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:24:49Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Add a link to all upstream e-d-s bugs for meego.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
See the list of [https://bugzilla.gnome.org/buglist.cgi?status_whiteboard_type=allwordssubstr;query_format=advanced;field0-0-0=product;status_whiteboard=meego;bug_status=UNCONFIRMED;bug_status=NEW;bug_status=ASSIGNED;bug_status=REOPENED;bug_status=NEEDINFO;type0-0-0=substring;value0-0-0=Evolution-Data-Server &amp;quot;meego&amp;quot; bugs in the upstream evolution-data-server bugzilla].&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652179 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652180 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html]&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:22:12Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* More Efficient Access to Meta Data for Change Tracking */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652179 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652180 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html]&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:21:59Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* More Efficient Access to Meta Data for Change Tracking */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652179 libebook: Upstream evolution-data-server bug]&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652180 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html]&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:13:06Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Atomic Updates */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html]&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:12:41Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Contacts: Store PHOTO Data as Plain Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652178 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:09:15Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Contacts: Store PHOTO Data as Plain Files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
## If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
## If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:08:43Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Quick check for &amp;quot;data changed&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&amp;lt;BR&amp;gt;&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:08:23Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Quick check for &amp;quot;data changed&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652175 libebook: Upstream evolution-data-server bug]&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652177 libecal: Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:02:15Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Optional Parsing of ebook Data in Client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652173 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T10:01:35Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Asynchronous API for storing items in libecal */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652174 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T09:59:03Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Optional Parsing of ebook Data in Client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
[Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T09:48:48Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Optional Parsing of ebook Data in Client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch], already used in the Meego package, partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T09:48:10Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Optional Parsing of ebook Data in Client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 e_book_view_set_parse_vcards() patch] partly implements this already. This patch was taken from an old fremantle EDS patch that was never actually used, and is generally considered to be a bad hack that should not be accepted upstream.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T09:46:08Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Nofify with UIDs Only */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652172 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 patch] might partly implement this already.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T09:42:57Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Suppress Unnecessary Data Transfer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
[https://bugzilla.gnome.org/show_bug.cgi?id=652171 Upstream evolution-data-server bug]&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed. This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 patch] might partly implement this already.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T09:29:50Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Return UIDs Only: Let's change the notification signals instead.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Nofify with UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
EBookView emits signals when contacts are changed, added, or removed. But those signals sends lists of entire EContacts, containing the entire contact data, though we often have all the data already and just want to know which contacts have changed. This would allow easier integration with the QContact API, greatly improving performance.&lt;br /&gt;
&lt;br /&gt;
[http://developer.gnome.org/libebook/stable/EBook.html#e-book-get-book-view e_book_get_book_view()] takes an [http://developer.gnome.org/libebook/stable/libebook-e-book-query.html#EBookQuery EBookQuery] which could be extended to take a new flag to make the EBookView send only the UID in the signals' EContacts. For instance, &amp;quot;X-EDS-QUERY-FLAG-NOTIFY-UID-ONLY&amp;quot;. The UID is already stored separately for use as the primary key of the local-storage backend's BDB database, so no VCard parsing should be necessary to provide it.&lt;br /&gt;
&lt;br /&gt;
Note that users of this feature should probably use just the base EVCard API on the provided EContact objects, to avoid extra processing and caching in the EContact code.&lt;br /&gt;
&lt;br /&gt;
Note: We previously considered implementing e_book_get_book_view()'s requested fields parameter, but that changes the whole view, though we only really want to change what is sent for changed/new contacts.&lt;br /&gt;
&lt;br /&gt;
Note: Chris discovered a dedicated e_book_get_contact_uids() API in the Fremantle EDS fork. The new API call was accepted upstream (in master) and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32 branch, but this is not a full solution.&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 patch] might partly implement this already.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T08:54:34Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Return UIDs Only */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 patch] might partly implement this already.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T08:52:59Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Return UIDs Only */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11|backported as a patch] (used in the Meego package) for the gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 patch] might partly implement this already.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-09T08:39:25Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: A change of plan about what branch to target first.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the evolution-data-server gnome-2-32 branch, as used by MeeGo 1.2, then ported to master for review by upstream maintainers. Most changes will not be accepted in upstream's gnome-2-32 branch, because is is stable, but Meego will apply them as patches to its package.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
* https://bugs.meego.com/show_bug.cgi?id=18760 - &amp;quot;QtContacts-EDS + EDS: more flexible EBookView (UID only, only future changes)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 patch] might partly implement this already.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
Making libical asynchronous is almost impossible without going multithreaded. Let's focus on e_cal D-Bus communication first.&lt;br /&gt;
&lt;br /&gt;
Rob started some work on this in the rbradford-wip-ecal-async-api branch. Perhaps you can reuse some of that work. It is not functional, but might be a source of inspiration or code fragments.&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T12:48:54Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Optional Parsing of ebook Data in Client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
An existing (and in use) [http://build.meego.com/package/view_file?file=EBookView-Implement-delayed-vcard-parsing.patch&amp;amp;package=evolution-data-server&amp;amp;project=eds&amp;amp;srcmd5=977d2b885bed818cb616599749407e79 patch] might partly implement this already.&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T12:41:05Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: /* Return UIDs Only: Link to the patch that's already in use.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and [https://bugzilla.gnome.org/show_bug.cgi?id=651446#c11 backported as a patch] (used in the Meego package) for the gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T11:57:01Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and backported to gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== Asynchronous API for storing items in libecal ==&lt;br /&gt;
&lt;br /&gt;
libecal should allow the caller to request storing of data without blocking on processing of the data. It should notify the caller when the data has been stored, or when processing has failed.&lt;br /&gt;
&lt;br /&gt;
These functions may require async versions:&lt;br /&gt;
* icalcomponent_new_from_string()&lt;br /&gt;
* e_cal_modify_object[_with_mod]&lt;br /&gt;
* e_cal_create_object()&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/syncevolution/syncevolution-improvements</id>
		<title>Architecture/planning/syncevolution/syncevolution-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/syncevolution/syncevolution-improvements"/>
				<updated>2011-06-08T11:38:04Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Created page with &amp;quot;= SyncEvolution Improvements =   * [https://bugs.meego.com/show_bug.cgi?id=736#c2 Detect Manufacturer/Model via Bluetooth] * [https://bugs.meego.com/show_bug.cgi?id=1351#c1 Initi...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SyncEvolution Improvements = &lt;br /&gt;
&lt;br /&gt;
* [https://bugs.meego.com/show_bug.cgi?id=736#c2 Detect Manufacturer/Model via Bluetooth]&lt;br /&gt;
* [https://bugs.meego.com/show_bug.cgi?id=1351#c1 Initial refactoring: Reorganization of code]&lt;br /&gt;
* [https://bugs.meego.com/show_bug.cgi?id=716#c2 Refactor code to use forked processes]&lt;br /&gt;
* [https://bugs.meego.com/show_bug.cgi?id=1351 Syncevo-dbus-server Clean Up (Complete rewrite to deal with arising issues)]&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T11:29:53Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Move Future stuff to the bottom.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and backported to gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T11:23:21Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Optional Parsing of ebook Data in Client: Add some explanatory text.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== Future: Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
Currently not planned. Depends on the future MeeGo security infrastructure.&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
Chris discovered a dedicated API for this in the Fremantle EDS fork. The new API call was accepted upstream and backported to gnome-2-32, so no further work is needed?&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
The EDS client-side APIs currently parse and (temporarily) store the parsed details of VCards. However, this is often unnecessary because APIs such as e_book_get_book_view() cause it to return the whole VCard anyway. There will be some performance gain from delaying VCard parsing until it is really needed by calls to functions such as e_contact_new_from_vcard(). &lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T10:11:40Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Title capitalization&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== Content Protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
== Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress Unnecessary Data Transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs Only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
== Optional Parsing of ebook Data in Client ==&lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== More Efficient Access to Meta Data for Change Tracking ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== Contacts: Store PHOTO Data as Plain Files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T10:10:03Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: quick check for &amp;quot;data changed: clarification&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== content protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
== change tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress unnecessary data transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
== optional parsing of ebook data in client ==&lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== More efficient access to meta data for change tracking + atomic updates ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== Quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
The libebook and libical APIs should offer a way to discover if any data whatsoever has changed. This would, for instance, help SyncEvolution to avoid unnecessary detailed checking. This could just check the modification dates of local storage files, such as the BDB .db file, or .ics file, as long as we do not use those files to store permanent caches of parsed data. This would be much quicker than listing items for the whole database and comparing their revisions strings, as is currently necessary.&lt;br /&gt;
&lt;br /&gt;
This would require small API additions, to check that the opaque revision strings are unchanged, such as&lt;br /&gt;
&lt;br /&gt;
 gchar* e_book_get_revision(EBook *book)&lt;br /&gt;
 gboolean e_book_check_revision(EBook *book , const gchar* revision)&lt;br /&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
 gchar* e_cal_get_revision(ECal *ecal)&lt;br /&gt;
 gboolean e_cal_check_revision(ECal ecal, const gchar revision)&lt;br /&gt;
&lt;br /&gt;
The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine if it has really changed. This will be the case for non-local storage.&lt;br /&gt;
* If it is non-empty and the same as before, the nothing has changed. No further check will be necessary.&lt;br /&gt;
&lt;br /&gt;
== contacts: store PHOTO data as plain files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T10:03:26Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: More efficient access to meta data for change tracking + atomic updates: Split and clarify slightly.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== content protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
== change tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress unnecessary data transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
== optional parsing of ebook data in client ==&lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== More efficient access to meta data for change tracking + atomic updates ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
The Maemo Fremantle port of EDS, which is of course already open source, apparently has some solution for this, according to Mathias Hasselman, so that should be investigated first.&lt;br /&gt;
&lt;br /&gt;
However, this should probably be made possible by:&lt;br /&gt;
&lt;br /&gt;
# Extending the EDS query language with a flag that limits the delivered data to just:&lt;br /&gt;
## UID and REV for libebook (REV is in VCard 3.0)&lt;br /&gt;
## UID+RECURRENCE-ID+LAST-MODIFIED, for libecal &lt;br /&gt;
# Implementing these queries for the local contact and calendar backends. The query would be rejected, with an error, for other backends.&lt;br /&gt;
&lt;br /&gt;
== Atomic Updates ==&lt;br /&gt;
&lt;br /&gt;
Later, implement atomic changes as discussed in the mail thread: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html&lt;br /&gt;
&lt;br /&gt;
== quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
Even quicker than listing items and comparing their revisions strings would be a comparison of a revision string for the whole database. The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine that.&lt;br /&gt;
* If it is non-empty and the same as before, nothing has changed. No further check necessary.&lt;br /&gt;
&lt;br /&gt;
The modification time stamp of the .ics or .db files could be used. Probably need a new &amp;quot;query property&amp;quot; API. e_cal_get_static_capability() only returns bool. Same with e_book_get_static_capabilities()/e_book_check_static_capability().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== contacts: store PHOTO data as plain files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T09:54:29Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: client parsing in libical is not actually necessary. While mplementing KCal-EDS, Patrick Ohly found that the parsing of iCalendar 2.0 data into libical can be done in libecal without causing overhead&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== content protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
== change tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress unnecessary data transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
== optional parsing of ebook data in client ==&lt;br /&gt;
&lt;br /&gt;
libebook provides different functionality:&lt;br /&gt;
# exchange data as vCard with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts replaces the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
&lt;br /&gt;
Note that libecal (for iCalendar) can already do this, though libebook can't yet.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string())) or only if requested? How would that be configured by a libebook user?&lt;br /&gt;
&lt;br /&gt;
== more efficient access to meta data for change tracking + atomic updates ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# extend EDS query language with a flag that limits delivered data to just UID+RECURRENCE-ID+LAST-MODIFIED resp. UID+REV&lt;br /&gt;
# implement this query for local contact and calendar storage, reject with error in others&lt;br /&gt;
# later: implement atomic changes as discussed in the mail thread&lt;br /&gt;
&lt;br /&gt;
== quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
Even quicker than listing items and comparing their revisions strings would be a comparison of a revision string for the whole database. The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine that.&lt;br /&gt;
* If it is non-empty and the same as before, nothing has changed. No further check necessary.&lt;br /&gt;
&lt;br /&gt;
The modification time stamp of the .ics or .db files could be used. Probably need a new &amp;quot;query property&amp;quot; API. e_cal_get_static_capability() only returns bool. Same with e_book_get_static_capabilities()/e_book_check_static_capability().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== contacts: store PHOTO data as plain files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T09:48:43Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: Contacts: store PHOTO data as plain files: Clarify the text slightly.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== content protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
== change tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress unnecessary data transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
== optional parsing of data in client ==&lt;br /&gt;
&lt;br /&gt;
libebook/ecal provide different functionality:&lt;br /&gt;
# exchange data as vCard/iCalendar with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore replace the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook/libecal:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
* e_cal_get_object_list_as_comp()/asynchronous read/view + e_cal_get_component_as_string()&lt;br /&gt;
* icalcomponent_new_from_string() + e_cal_modify_object[_with_mod]()/e_cal_create_object()&lt;br /&gt;
* e_cal_get_object_list_as_comp()/e_cal_get_object()/asynchronous view + e_cal_get_component_as_string()&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
# add delayed parsing to libical, again triggered by API call&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string()/icalcomponent_new_from_string()) or only if requested? How would that be configured by a libebook/libecal user?&lt;br /&gt;
&lt;br /&gt;
== more efficient access to meta data for change tracking + atomic updates ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# extend EDS query language with a flag that limits delivered data to just UID+RECURRENCE-ID+LAST-MODIFIED resp. UID+REV&lt;br /&gt;
# implement this query for local contact and calendar storage, reject with error in others&lt;br /&gt;
# later: implement atomic changes as discussed in the mail thread&lt;br /&gt;
&lt;br /&gt;
== quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
Even quicker than listing items and comparing their revisions strings would be a comparison of a revision string for the whole database. The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine that.&lt;br /&gt;
* If it is non-empty and the same as before, nothing has changed. No further check necessary.&lt;br /&gt;
&lt;br /&gt;
The modification time stamp of the .ics or .db files could be used. Probably need a new &amp;quot;query property&amp;quot; API. e_cal_get_static_capability() only returns bool. Same with e_book_get_static_capabilities()/e_book_check_static_capability().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== contacts: store PHOTO data as plain files ==&lt;br /&gt;
&lt;br /&gt;
Photos should be transferred over D-Bus via a filepath to a local file rather than transferring the actual photo data over D-Bus. The VCard format already allows this option (See the PHOTO property). We must be careful to keep these local files in sync and to remove them when contacts are removed, and to restrict access to the files from other processes. &lt;br /&gt;
&lt;br /&gt;
There should be utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	<entry>
		<id>http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements</id>
		<title>Architecture/planning/evolution-data-server/eds-improvements</title>
		<link rel="alternate" type="text/html" href="http://wiki.meego.com/Architecture/planning/evolution-data-server/eds-improvements"/>
				<updated>2011-06-08T09:45:08Z</updated>
		
		<summary type="html">&lt;p&gt;Murrayc: change tracking: Make the work to be done clearer.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes improvements that are desirable or even essential for good performance of Evolution Data Server (EDS) as PIM storage in MeeGo.&lt;br /&gt;
&lt;br /&gt;
All of these changes should be developed for the EDS master branch, reviewed by upstream maintainers and then back-ported to EDS 2.32, the version in MeeGo.&lt;br /&gt;
&lt;br /&gt;
== content protection ==&lt;br /&gt;
&lt;br /&gt;
Only authorized applications (= processes) with the necessary permissions should be able to read/write data. Exact permissions and mechanisms for verifying them to be defined as part of the (revised?) MeeGo architecture.&lt;br /&gt;
&lt;br /&gt;
This can be added as follows:&lt;br /&gt;
# lock down file permissions&lt;br /&gt;
# add permission checks to EDS D-Bus servers&lt;br /&gt;
&lt;br /&gt;
== change tracking ==&lt;br /&gt;
&lt;br /&gt;
EDS is based on the model/view/controller principle: an application opens a database (calendar or addressbook) and requests a view with server-side filtering, then the application is sent:&lt;br /&gt;
# all data covered by the view&lt;br /&gt;
# the &amp;quot;all data sent&amp;quot; signal&lt;br /&gt;
# changes (add/update/remove) while the view exists&lt;br /&gt;
&lt;br /&gt;
Applications modify data with asynchronous requests (controller) and keep showing the old data until the change notification comes in. The exact changes made to the data are determined by the server (for example when meeting invitations are sent).&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore do not have such a strict model. With QtContacts the app simply loads and stores contacts and is responsible for maintaining its own view. Changes are sent for changes made after the database was opened. KCalCore is based on the concept of loading a calendar (partially) into the client, modifying it there, then writing it back. Changes are also sent while the storage is open.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
&lt;br /&gt;
=== Suppress unnecessary data transfer ===&lt;br /&gt;
&lt;br /&gt;
EDS currently sends all data when a view is requested, which is unnecessary when the client is only interested in change notifications. An extension to the EDS query language could optionally suppresses that sending of existing data when the view is opened, to be implemented only for the local contacts and calendar backends. This would allow easier integration with the QContact API.&lt;br /&gt;
&lt;br /&gt;
The Fremantle EDS fork also had a “freezable” (static) capability for libebook, which should probably be investigated. See, for instance: http://maemo.org/api_refs/5.0/5.0-final/libebook/EBookView.html#e-book-view-set-freezable &lt;br /&gt;
&lt;br /&gt;
One possibility for adding the flag is to (ab)use the existing query language with a match for special fields:&lt;br /&gt;
* in the client: query = e_book_query_orv(e_book_query_field_exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;), &amp;lt;real query&amp;gt;, NULL);&lt;br /&gt;
* in the server: &amp;quot;if (query is OR-Query and first clause is exists(&amp;quot;X-EDS-QUERY-FLAG-SKIP-DATA-DUMP&amp;quot;)) { skip_data_dump = TRUE; query = second clause; }&lt;br /&gt;
&lt;br /&gt;
=== Return UIDs only ===&lt;br /&gt;
&lt;br /&gt;
The e_book_get_book_view() function takes a list of requested fields, to avoid returning unnecessary data, but this is apparently ignored for the local contacts backend. It would anyway require extra parsing and generation of smaller VCards, losing some possible advantages from delayed parsing of VCards.&lt;br /&gt;
&lt;br /&gt;
However, the UID is already stored separately for use as the primary key of the BDB database, so it would be worthwhile to support that particular requested field. This would allow easier integration with the QContact API. It would also offer much better performance in cases where the client already has the data but just wants to discover what subset of that data meets a certain criteria.&lt;br /&gt;
&lt;br /&gt;
== optional parsing of data in client ==&lt;br /&gt;
&lt;br /&gt;
libebook/ecal provide different functionality:&lt;br /&gt;
# exchange data as vCard/iCalendar with EDS daemon&lt;br /&gt;
# parse items and wrap them in a C API&lt;br /&gt;
&lt;br /&gt;
QtContacts and KCalCore replace the second part. An obvious performance improvement is to only do the second part if the additional C APIs are really called. The following calls then transfer data without any additional parsing in libebook/libecal:&lt;br /&gt;
* e_book_get_contact()/asynchronous read/view + e_vcard_to_string()&lt;br /&gt;
* e_contact_new_from_vcard() + e_book_add_contact()/e_book_commit_contact()/asynchronous storing&lt;br /&gt;
* e_cal_get_object_list_as_comp()/asynchronous read/view + e_cal_get_component_as_string()&lt;br /&gt;
* icalcomponent_new_from_string() + e_cal_modify_object[_with_mod]()/e_cal_create_object()&lt;br /&gt;
* e_cal_get_object_list_as_comp()/e_cal_get_object()/asynchronous view + e_cal_get_component_as_string()&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# add delayed parsing to libebook, triggered by API call which needs parsed data&lt;br /&gt;
# add delayed parsing to libical, again triggered by API call&lt;br /&gt;
&lt;br /&gt;
PROBLEM:&lt;br /&gt;
# If delayed parsing fails, how can error be reported?&lt;br /&gt;
# Should delayed parsing be done always (e_vcard_to_string()/icalcomponent_new_from_string()) or only if requested? How would that be configured by a libebook/libecal user?&lt;br /&gt;
&lt;br /&gt;
== more efficient access to meta data for change tracking + atomic updates ==&lt;br /&gt;
&lt;br /&gt;
This was discussed a while ago: [[http://www.mail-archive.com/evolution-hackers@gnome.org/msg03029.html &lt;br /&gt;
[Evolution-hackers] concurrent modifications of items in GUI and EDS database]]&lt;br /&gt;
&lt;br /&gt;
Data synchronization only needs to know which items exist (list of local IDs) and which revision of each item is currently stored. Revisions can be identified with a string which changes for each modification. Restoring an older revision should (but doesn't have to) restore the revision string.&lt;br /&gt;
&lt;br /&gt;
For calendar, UID+RECURRENCE-ID and LAST-MODIFIED can be used. For contacts, UID + REV.&lt;br /&gt;
&lt;br /&gt;
By comparing a stored list against the current one, changes can be detected without relying on journals in the daemon or comparison of time stamps. Journals are hard to maintain (how many of them, how long?). Comparison of time stamps has problems when changes are allowed while a sync runs and assumes that system time is linear (which is not always true).&lt;br /&gt;
&lt;br /&gt;
As an additional use case, local ID + revision string could be used to prevent overwriting stale data in the server, as in HTTP PUT eTag checks.&lt;br /&gt;
&lt;br /&gt;
TODO:&lt;br /&gt;
# extend EDS query language with a flag that limits delivered data to just UID+RECURRENCE-ID+LAST-MODIFIED resp. UID+REV&lt;br /&gt;
# implement this query for local contact and calendar storage, reject with error in others&lt;br /&gt;
# later: implement atomic changes as discussed in the mail thread&lt;br /&gt;
&lt;br /&gt;
== quick check for &amp;quot;data changed&amp;quot; ==&lt;br /&gt;
&lt;br /&gt;
Even quicker than listing items and comparing their revisions strings would be a comparison of a revision string for the whole database. The semantic would be this:&lt;br /&gt;
* If the revision string is empty or different, then the content of the database '''might''' have changed. A more detailed check is necessary to determine that.&lt;br /&gt;
* If it is non-empty and the same as before, nothing has changed. No further check necessary.&lt;br /&gt;
&lt;br /&gt;
The modification time stamp of the .ics or .db files could be used. Probably need a new &amp;quot;query property&amp;quot; API. e_cal_get_static_capability() only returns bool. Same with e_book_get_static_capabilities()/e_book_check_static_capability().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== contacts: store PHOTO data as plain files ==&lt;br /&gt;
&lt;br /&gt;
Transfering PHOTO data over D-Bus as base64 encoded data in each vCard has obvious performance issues. Instead the PHOTO property should be a link to a local file (supported by vCard), with utility code available to libebook users to convert between the different representations.&lt;br /&gt;
&lt;br /&gt;
Goals:&lt;br /&gt;
# Apps should be able to create photo files without ever passing the data to libebook.&lt;br /&gt;
# External PHOTO file and corresponding contact must be kept in sync:&lt;br /&gt;
** If a contact is deleted, the photo also needs to be removed.&lt;br /&gt;
** If a photo file is created and then storing the contact fails, who removes the file?&lt;br /&gt;
# Access to photo data must be limited to processes which have the right permissions.&lt;br /&gt;
&lt;br /&gt;
Proposal:&lt;br /&gt;
* For each ~/.local/share/evolution/foo calendar, store photos in &amp;lt;photo path&amp;gt;=~/.local/share/evolution/foo/photos, with same permissions.&lt;br /&gt;
* New photo files are created with a [http://en.wikipedia.org/wiki/Universally_unique_identifier UUID] as base name and suffix according to the file content.&lt;br /&gt;
* If a contact is deleted and has a PHOTO;VALUE=uri:file://&amp;lt;photo path&amp;gt;/*, delete that file.&lt;br /&gt;
* For apps which want to create the photo file directly:&lt;br /&gt;
** Apps get a file descriptor and the path from a new libebook API.&lt;br /&gt;
** They own the file until the EDS server acknowledges the successful storing of a contact with a matching PHOTO;VALUE=uri:file property. If that fails, the app must remove the file.&lt;br /&gt;
* Add new API calls to libebook which split out resp. include data inline.&lt;br /&gt;
** Must track ownership of file after splitting it out and before storing - might never get stored!&lt;br /&gt;
&lt;br /&gt;
Open:&lt;br /&gt;
* Should there be automatic garbage collection of stale photos in case something went wrong and a photo wasn't properly deleted?&lt;br /&gt;
* Trust TYPE=JPEG/PNG/... or look into file content to determine type?&lt;/div&gt;</summary>
		<author><name>Murrayc</name></author>	</entry>

	</feed>