1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* A class to cache address book conents on local file system
4 * Copyright (C) 2004 Novell, Inc.
6 * Authors: Sivaiah Nallagatla <snallagatla@novell.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU Lesser General Public
10 * License as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 #include "e-book-backend-cache.h"
28 #include "e-book-backend-sexp.h"
30 struct _EBookBackendCachePrivate {
40 static GObjectClass *parent_class = NULL;
43 get_filename_from_uri (const char *uri)
45 char *mangled_uri, *filename;
48 /* mangle the URI to not contain invalid characters */
49 mangled_uri = g_strdup (uri);
50 for (i = 0; i < strlen (mangled_uri); i++) {
51 switch (mangled_uri[i]) {
58 /* generate the file name */
59 filename = g_build_filename (g_get_home_dir (), ".evolution/cache/addressbook",
60 mangled_uri, "cache.xml", NULL);
69 e_book_backend_cache_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
71 EBookBackendCache *cache;
72 EBookBackendCachePrivate *priv;
75 cache = E_BOOK_BACKEND_CACHE (object);
78 switch (property_id) {
80 cache_file = get_filename_from_uri (g_value_get_string (value));
84 g_object_set (G_OBJECT (cache), "filename", cache_file, NULL);
89 priv->uri = g_value_dup_string (value);
92 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
97 e_book_backend_cache_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
99 EBookBackendCache *cache;
100 EBookBackendCachePrivate *priv;
102 cache = E_BOOK_BACKEND_CACHE (object);
105 switch (property_id) {
107 g_value_set_string (value, priv->uri);
110 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
116 e_book_backend_cache_finalize (GObject *object)
118 EBookBackendCache *cache;
119 EBookBackendCachePrivate *priv;
121 cache = E_BOOK_BACKEND_CACHE (object);
135 parent_class->finalize (object);
139 e_book_backend_cache_constructor (GType type,
140 guint n_construct_properties,
141 GObjectConstructParam *construct_properties)
147 /* Invoke parent constructor. */
148 obj = parent_class->constructor (type,
149 n_construct_properties,
150 construct_properties);
153 if (!g_ascii_strcasecmp ( g_param_spec_get_name (construct_properties->pspec), "uri")) {
154 uri = g_value_get_string (construct_properties->value);
155 cache_file = get_filename_from_uri (uri);
157 g_object_set (obj, "filename", cache_file, NULL);
165 e_book_backend_cache_class_init (EBookBackendCacheClass *klass)
167 GObjectClass *object_class;
169 parent_class = g_type_class_peek_parent (klass);
171 object_class = G_OBJECT_CLASS (klass);
172 object_class->finalize = e_book_backend_cache_finalize;
173 object_class->set_property = e_book_backend_cache_set_property;
174 object_class->get_property = e_book_backend_cache_get_property;
176 object_class->constructor = e_book_backend_cache_constructor;
177 g_object_class_install_property (object_class, PROP_URI,
178 g_param_spec_string ("uri", NULL, NULL, "",
179 G_PARAM_READABLE | G_PARAM_WRITABLE
180 | G_PARAM_CONSTRUCT_ONLY));
184 e_book_backend_cache_init (EBookBackendCache *cache)
186 EBookBackendCachePrivate *priv;
188 priv = g_new0 (EBookBackendCachePrivate, 1);
196 e_book_backend_cache_get_type (void)
198 static GType type = 0;
201 static GTypeInfo info = {
202 sizeof (EBookBackendCacheClass),
203 (GBaseInitFunc) NULL,
204 (GBaseFinalizeFunc) NULL,
205 (GClassInitFunc) e_book_backend_cache_class_init,
207 sizeof (EBookBackendCache),
209 (GInstanceInitFunc) e_book_backend_cache_init,
211 type = g_type_register_static (E_TYPE_FILE_CACHE, "EBookBackendCache", &info, 0);
218 * e_book_backend_cache_new
219 * @uri: URI of the backend to be cached.
221 * Creates a new #EBookBackendCache object, which implements a local
222 * cache of #EContact objects, useful for remote backends.
224 * Return value: A new #EBookBackendCache.
227 e_book_backend_cache_new (const char *uri)
229 EBookBackendCache *cache;
231 cache = g_object_new (E_TYPE_BOOK_BACKEND_CACHE, "uri", uri, NULL);
237 * e_book_backend_cache_get_contact:
238 * @cache: an #EBookBackendCache
239 * @uid: a unique contact ID
241 * Get a cached contact. Note that the returned #EContact will be
242 * newly created, and must be unreffed by the caller when no longer
245 * Return value: A cached #EContact, or %NULL if @uid is not cached.
248 e_book_backend_cache_get_contact (EBookBackendCache *cache, const char *uid)
250 const char *vcard_str;
251 EContact *contact = NULL;
253 g_return_val_if_fail (E_IS_BOOK_BACKEND_CACHE (cache), NULL);
254 g_return_val_if_fail (uid != NULL, NULL);
256 vcard_str = e_file_cache_get_object (E_FILE_CACHE (cache), uid);
258 contact = e_contact_new_from_vcard (vcard_str);
267 * e_book_backend_cache_add_contact:
268 * @cache: an #EBookBackendCache
269 * @contact: an #EContact
271 * Adds @contact to @cache.
273 * Return value: %TRUE if the contact was cached successfully, %FALSE otherwise.
276 e_book_backend_cache_add_contact (EBookBackendCache *cache,
282 EBookBackendCachePrivate *priv;
284 g_return_val_if_fail (E_IS_BOOK_BACKEND_CACHE (cache), FALSE);
289 uid = e_contact_get_const (contact, E_CONTACT_UID);
290 vcard_str = e_vcard_to_string (E_VCARD(contact), EVC_FORMAT_VCARD_30);
292 if (e_file_cache_get_object (E_FILE_CACHE (cache), uid))
293 retval = e_file_cache_replace_object (E_FILE_CACHE (cache), uid, vcard_str);
295 retval = e_file_cache_add_object (E_FILE_CACHE (cache), uid, vcard_str);
303 * e_book_backend_cache_remove_contact:
304 * @cache: an #EBookBackendCache
305 * @uid: a unique contact ID
307 * Removes the contact identified by @uid from @cache.
309 * Return value: %TRUE if the contact was found and removed, %FALSE otherwise.
312 e_book_backend_cache_remove_contact (EBookBackendCache *cache,
317 EBookBackendCachePrivate *priv;
319 g_return_val_if_fail (E_IS_BOOK_BACKEND_CACHE (cache), FALSE);
320 g_return_val_if_fail (uid != NULL, FALSE);
325 if (!e_file_cache_get_object (E_FILE_CACHE (cache), uid)) {
329 retval = e_file_cache_remove_object (E_FILE_CACHE (cache), uid);
336 * e_book_backend_cache_check_contact:
337 * @cache: an #EBookBackendCache
338 * @uid: a unique contact ID
340 * Checks if the contact identified by @uid exists in @cache.
342 * Return value: %TRUE if the cache contains the contact, %FALSE otherwise.
345 e_book_backend_cache_check_contact (EBookBackendCache *cache, const char *uid)
349 EBookBackendCachePrivate *priv;
351 g_return_val_if_fail (E_IS_BOOK_BACKEND_CACHE (cache), FALSE);
352 g_return_val_if_fail (uid != NULL, FALSE);
357 if (e_file_cache_get_object (E_FILE_CACHE (cache), uid))
363 * e_book_backend_cache_get_contacts:
364 * @cache: an #EBookBackendCache
365 * @query: an s-expression
367 * Returns a list of #EContact elements from @cache matching @query.
368 * When done with the list, the caller must unref the contacts and
371 * Return value: A #GList of pointers to #EContact.
374 e_book_backend_cache_get_contacts (EBookBackendCache *cache, const char *query)
380 EBookBackendSExp *sexp = NULL;
383 g_return_val_if_fail (E_IS_BOOK_BACKEND_CACHE (cache), NULL);
385 sexp = e_book_backend_sexp_new (query);
391 lcache = l = e_file_cache_get_objects (E_FILE_CACHE (cache));
393 for ( ; l != NULL; l = g_slist_next (l)) {
395 if (vcard_str && !strncmp (vcard_str, "BEGIN:VCARD", 11)) {
396 contact = e_contact_new_from_vcard (vcard_str);
397 uid = e_contact_get_const (contact, E_CONTACT_UID);
398 if (contact && uid && *uid &&(query && e_book_backend_sexp_match_contact(sexp, contact)))
399 list = g_list_prepend (list, contact);
401 g_object_unref (contact);
406 g_slist_free (lcache);
408 g_object_unref (sexp);
410 return g_list_reverse (list);
414 * e_book_backend_cache_search:
415 * @cache: an #EBookBackendCache
416 * @query: an s-expression
418 * Returns an array of pointers to unique contact ID strings for contacts
419 * in @cache matching @query. When done with the array, the caller must
420 * free the ID strings and the array.
422 * Return value: A #GPtrArray of pointers to contact ID strings.
425 e_book_backend_cache_search (EBookBackendCache *cache, const char *query)
427 GList *matching_contacts, *temp;
428 GPtrArray *ptr_array;
430 matching_contacts = e_book_backend_cache_get_contacts (cache, query);
431 ptr_array = g_ptr_array_new ();
433 temp = matching_contacts;
434 for (; matching_contacts != NULL; matching_contacts = g_list_next (matching_contacts)) {
435 g_ptr_array_add (ptr_array, e_contact_get (matching_contacts->data, E_CONTACT_UID));
436 g_object_unref (matching_contacts->data);
444 * e_book_backend_cache_exists:
445 * @uri: URI for the cache
447 * Checks if an #EBookBackendCache exists at @uri.
449 * Return value: %TRUE if cache exists, %FALSE if not.
452 e_book_backend_cache_exists (const char *uri)
455 gboolean exists = FALSE;
456 file_name = get_filename_from_uri (uri);
458 if (file_name && g_file_test (file_name, G_FILE_TEST_EXISTS)) {
467 * e_book_backend_cache_set_populated:
468 * @cache: an #EBookBackendCache
470 * Flags @cache as being populated - that is, it is up-to-date on the
471 * contents of the book it's caching.
474 e_book_backend_cache_set_populated (EBookBackendCache *cache)
476 g_return_if_fail (E_IS_BOOK_BACKEND_CACHE (cache));
477 e_file_cache_add_object (E_FILE_CACHE (cache), "populated", "TRUE");
482 * e_book_backend_cache_is_populated:
483 * @cache: an #EBookBackendCache
485 * Checks if @cache is populated.
487 * Return value: %TRUE if @cache is populated, %FALSE otherwise.
490 e_book_backend_cache_is_populated (EBookBackendCache *cache)
492 g_return_val_if_fail (E_IS_BOOK_BACKEND_CACHE (cache), FALSE);
493 if (e_file_cache_get_object (E_FILE_CACHE (cache), "populated"))
499 e_book_backend_cache_set_time (EBookBackendCache *cache, const char *t)
501 g_return_if_fail (E_IS_BOOK_BACKEND_CACHE (cache));
502 e_file_cache_add_object (E_FILE_CACHE (cache), "last_update_time", t);
506 e_book_backend_cache_get_time (EBookBackendCache *cache)
508 g_return_val_if_fail (E_IS_BOOK_BACKEND_CACHE (cache), NULL);
509 return g_strdup (e_file_cache_get_object (E_FILE_CACHE (cache), "last_update_time"));