Store contacts as vCards/VCF files instead of SQLite (was: "Rock solid contacts")

asked 2016-06-23 13:04:29 +0300

hammerhead gravatar image

updated 2016-06-23 13:06:30 +0300

As depicted in the two bugs I just published, syncing contacts seems to be far from optimal.

From experience, crafting CardDav-friendly contact editing is a tough job with many pitfalls.

Why not simplify the whole topic and just store plain VCF files in a filesystem directory per account?

Then the whole CardDav issue can be solved using something like vdirsyncer and most issues are resolved.

(I mention vdirsyncer because in my evaluation it's the only one that works reliably and uses plain VCF files as opposed to alien formats or databases.)

edit retag flag offensive close delete



A variety of reasons, including performance and atomicity.

From the performance perspective, we aim for 60fps rendering. You can imagine that the user could flick a list, rendering at 60fps, and each frame you need to show 10 list entries, so this requires reading data for 600 contacts per second. Certainly some of the work can be done via caching and so forth, but in general the performance bottleneck of just the system calls (stat / open / read) to deal with that many files would be prohibitively expensive.

From the atomicity perspective, contact aggregation and linking often requires touching multiple contacts in a single atomic write. You can't do this across multiple files in a safe manner, whereas sqlite3 provides exceptional atomicity and integrity.

chris.adams ( 2016-06-24 06:54:14 +0300 )edit

In regards to performance that may simply be resolved by naming the VCF files so they contain data meant to appear in lists (their FN property, for example). I'm pretty confident a simple file listing is faster than any SQL query.

As for atomicity, would you mind throwing me an example?

hammerhead ( 2016-06-27 00:16:37 +0300 )edit

There are multiple pieces of data which need to appear in the lists (for example, a star if they are a favourite, their avatar, and their display name. In call history lists we may even need phone numbers, and in email recipient lists we may need email addresses. And so on). So unless you mean to encode all of that information into the filename, your approach will not work.

In regards to atomicity, take the example where a synchronisation pulls in an update to a data field for a Google contact which is linked to multiple other contacts (e.g., from Exchange and from Fruux). We need to update that Google contact, and also bubble the data change up to the aggregate contact (which contains the data from all linked contacts) within a single transaction.

chris.adams ( 2016-06-27 04:20:43 +0300 )edit