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) 1999-2008 Novell, Inc. (www.novell.com)
6 * Authors: Devashish Sharma <sdevashish@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.
26 #include <libedataserver/e-data-server-util.h>
27 #include "e-book-backend-db-cache.h"
28 #include "e-book-backend.h"
29 #include "e-book-backend-sexp.h"
32 string_to_dbt (const gchar *str,
35 memset (dbt, 0, sizeof (dbt));
36 dbt->data = (gpointer) str;
37 dbt->size = strlen (str) + 1;
38 dbt->flags = DB_DBT_USERMEM;
42 get_filename_from_uri (const gchar *uri)
44 const gchar *user_cache_dir;
45 gchar *mangled_uri, *filename;
47 user_cache_dir = e_get_user_cache_dir ();
49 /* Mangle the URI to not contain invalid characters. */
50 mangled_uri = g_strdelimit (g_strdup (uri), ":/", '_');
52 filename = g_build_filename (
53 user_cache_dir, "addressbook",
54 mangled_uri, "cache.db", NULL);
62 * e_book_backend_db_cache_set_filename:
64 * @filename: filename to be set
66 * Set the filename for db cacahe file.
70 e_book_backend_db_cache_set_filename (DB *db,
71 const gchar *filename)
73 DBT uid_dbt, vcard_dbt;
76 string_to_dbt ("filename", &uid_dbt);
77 string_to_dbt (filename, &vcard_dbt);
79 db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
81 g_warning ("db->put failed with %d", db_error);
87 * e_book_backend_db_cache_get_filename:
90 * Get the filename for db cacahe file.
94 e_book_backend_db_cache_get_filename (DB *db)
96 DBT uid_dbt, vcard_dbt;
100 string_to_dbt ("filename", &uid_dbt);
101 memset (&vcard_dbt, 0 , sizeof (vcard_dbt));
102 vcard_dbt.flags = DB_DBT_MALLOC;
104 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0);
106 g_warning ("db-<get failed with %d", db_error);
110 filename = g_strdup (vcard_dbt.data);
111 g_free (vcard_dbt.data);
117 * e_book_backend_db_cache_get_contact:
119 * @uid: a unique contact ID
121 * Get a cached contact. Note that the returned #EContact will be
122 * newly created, and must be unreffed by the caller when no longer
125 * Returns: A cached #EContact, or %NULL if @uid is not cached.
128 e_book_backend_db_cache_get_contact (DB *db,
131 DBT uid_dbt, vcard_dbt;
133 EContact *contact = NULL;
135 g_return_val_if_fail (uid != NULL, NULL);
137 string_to_dbt (uid, &uid_dbt);
138 memset (&vcard_dbt, 0 , sizeof (vcard_dbt));
139 vcard_dbt.flags = DB_DBT_MALLOC;
141 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt,0);
143 g_warning ("db->get failed with %d", db_error);
147 contact = e_contact_new_from_vcard_with_uid ((const gchar *) vcard_dbt.data, uid);
148 g_free (vcard_dbt.data);
153 * e_book_backend_db_cache_add_contact:
155 * @contact: an #EContact
157 * Adds @contact to @cache.
159 * Returns: %TRUE if the contact was cached successfully, %FALSE otherwise.
162 e_book_backend_db_cache_add_contact (DB *db,
165 DBT uid_dbt, vcard_dbt;
170 uid = e_contact_get_const (contact, E_CONTACT_UID);
173 printf("name:%s, email:%s\n",
174 (gchar *) e_contact_get (contact, E_CONTACT_GIVEN_NAME),
175 (gchar *) e_contact_get (contact, E_CONTACT_EMAIL_1));
178 string_to_dbt (uid, &uid_dbt);
180 vcard_str = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
181 string_to_dbt (vcard_str, &vcard_dbt);
183 /* db_error = db->del (db, NULL, &uid_dbt, 0); */
184 db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
189 g_warning ("db->put failed with %d", db_error);
197 * e_book_backend_db_cache_remove_contact:
199 * @uid: a unique contact ID
201 * Removes the contact identified by @uid from @cache.
203 * Returns: %TRUE if the contact was found and removed, %FALSE otherwise.
206 e_book_backend_db_cache_remove_contact (DB *db,
213 g_return_val_if_fail (uid != NULL, FALSE);
215 string_to_dbt (uid, &uid_dbt);
216 db_error = db->del (db, NULL, &uid_dbt, 0);
219 g_warning ("db->del failed with %d", db_error);
228 * e_book_backend_db_cache_check_contact:
230 * @uid: a unique contact ID
232 * Checks if the contact identified by @uid exists in @cache.
234 * Returns: %TRUE if the cache contains the contact, %FALSE otherwise.
237 e_book_backend_db_cache_check_contact (DB *db,
240 DBT uid_dbt, vcard_dbt;
243 g_return_val_if_fail (uid != NULL, FALSE);
245 string_to_dbt (uid, &uid_dbt);
246 memset (&vcard_dbt, 0 , sizeof (vcard_dbt));
247 vcard_dbt.flags = DB_DBT_MALLOC;
249 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt,0);
253 free (vcard_dbt.data);
259 * e_book_backend_db_cache_get_contacts:
261 * @query: an s-expression
263 * Returns a list of #EContact elements from @cache matching @query.
264 * When done with the list, the caller must unref the contacts and
267 * Returns: A #GList of pointers to #EContact.
270 e_book_backend_db_cache_get_contacts (DB *db,
274 DBT uid_dbt, vcard_dbt;
277 EBookBackendSExp *sexp = NULL;
281 sexp = e_book_backend_sexp_new (query);
286 db_error = db->cursor (db, NULL, &dbc, 0);
288 g_warning ("db->cursor failed with %d", db_error);
290 g_object_unref (sexp);
294 memset (&vcard_dbt, 0 , sizeof (vcard_dbt));
295 memset (&uid_dbt, 0, sizeof (uid_dbt));
296 db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_FIRST);
298 while (db_error == 0) {
299 if (vcard_dbt.data && !strncmp (vcard_dbt.data, "BEGIN:VCARD", 11)) {
300 contact = e_contact_new_from_vcard (vcard_dbt.data);
302 if (e_book_backend_sexp_match_contact (sexp, contact))
303 list = g_list_prepend (list, contact);
305 g_object_unref (contact);
307 db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_NEXT);
310 db_error = dbc->c_close (dbc);
312 g_warning ("db->c_close failed with %d", db_error);
315 g_object_unref (sexp);
317 return g_list_reverse (list);
321 * e_book_backend_db_cache_search:
322 * @backend: an #EBookBackend
323 * @query: an s-expression
325 * Returns an array of pointers to unique contact ID strings for contacts
326 * in @cache matching @query. When done with the array, the caller must
327 * free the ID strings and the array.
329 * Returns: A #GPtrArray of pointers to contact ID strings.
332 e_book_backend_db_cache_search (DB *db,
335 GList *matching_contacts, *temp;
336 GPtrArray *ptr_array;
338 matching_contacts = e_book_backend_db_cache_get_contacts (db, query);
339 ptr_array = g_ptr_array_new ();
341 temp = matching_contacts;
342 for (; matching_contacts != NULL; matching_contacts = g_list_next (matching_contacts)) {
343 g_ptr_array_add (ptr_array, e_contact_get (matching_contacts->data, E_CONTACT_UID));
344 g_object_unref (matching_contacts->data);
352 * e_book_backend_db_cache_exists:
353 * @uri: URI for the cache
355 * Checks if an #EBookBackendCache exists at @uri.
357 * Returns: %TRUE if cache exists, %FALSE if not.
360 e_book_backend_db_cache_exists (const gchar *uri)
363 gboolean exists = FALSE;
364 file_name = get_filename_from_uri (uri);
366 if (file_name && g_file_test (file_name, G_FILE_TEST_EXISTS))
375 * e_book_backend_db_cache_set_populated:
376 * @backend: an #EBookBackend
378 * Flags @cache as being populated - that is, it is up-to-date on the
379 * contents of the book it's caching.
382 e_book_backend_db_cache_set_populated (DB *db)
384 DBT uid_dbt, vcard_dbt;
387 string_to_dbt ("populated", &uid_dbt);
388 string_to_dbt ("TRUE", &vcard_dbt);
389 db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
391 g_warning ("db->put failed with %d", db_error);
397 * e_book_backend_cache_is_populated:
400 * Checks if @cache is populated.
402 * Returns: %TRUE if @cache is populated, %FALSE otherwise.
405 e_book_backend_db_cache_is_populated (DB *db)
407 DBT uid_dbt, vcard_dbt;
410 string_to_dbt ("populated", &uid_dbt);
411 memset (&vcard_dbt, 0, sizeof (vcard_dbt));
412 vcard_dbt.flags = DB_DBT_MALLOC;
414 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0);
419 free (vcard_dbt.data);
425 * e_book_backend_db_cache_set_time:
430 e_book_backend_db_cache_set_time (DB *db,
433 DBT uid_dbt, vcard_dbt;
436 string_to_dbt ("last_update_time", &uid_dbt);
437 string_to_dbt (t, &vcard_dbt);
439 db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
441 g_warning ("db->put failed with %d", db_error);
446 * e_book_backend_db_cache_get_time:
451 e_book_backend_db_cache_get_time (DB *db)
453 DBT uid_dbt, vcard_dbt;
457 string_to_dbt ("last_update_time", &uid_dbt);
458 memset (&vcard_dbt, 0, sizeof (vcard_dbt));
459 vcard_dbt.flags = DB_DBT_MALLOC;
461 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0);
463 g_warning ("db->get failed with %d", db_error);
465 t = g_strdup (vcard_dbt.data);
466 free (vcard_dbt.data);