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: 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.
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 char *str, DBT *dbt)
34 memset(dbt, 0, sizeof(dbt));
35 dbt->data = (void *)str;
36 dbt->size = strlen(str) + 1;
37 dbt->flags = DB_DBT_USERMEM;
41 get_filename_from_uri (const char *uri)
43 char *mangled_uri, *filename;
46 /* mangle the URI to not contain invalid characters */
47 mangled_uri = g_strdup (uri);
48 for (i = 0; i < strlen (mangled_uri); i++) {
49 switch (mangled_uri[i]) {
56 /* generate the file name */
57 filename = g_build_filename (g_get_home_dir (), ".evolution/cache/addressbook",
58 mangled_uri, "cache.db", NULL);
67 * e_book_backend_db_cache_set_filename:
69 * @filename: filename to be set
71 * Set the filename for db cacahe file.
75 e_book_backend_db_cache_set_filename(DB *db, const char *filename)
77 DBT uid_dbt, vcard_dbt;
80 string_to_dbt ("filename", &uid_dbt);
81 string_to_dbt (filename, &vcard_dbt);
83 db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
85 g_warning ("db->put failed with %d", db_error);
91 * e_book_backend_db_cache_get_filename:
94 * Get the filename for db cacahe file.
98 e_book_backend_db_cache_get_filename(DB *db)
100 DBT uid_dbt, vcard_dbt;
104 string_to_dbt ("filename", &uid_dbt);
105 memset (&vcard_dbt, 0 , sizeof(vcard_dbt));
106 vcard_dbt.flags = DB_DBT_MALLOC;
108 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0);
110 g_warning ("db-<get failed with %d", db_error);
114 filename = g_strdup (vcard_dbt.data);
115 g_free (vcard_dbt.data);
121 * e_book_backend_db_cache_get_contact:
123 * @uid: a unique contact ID
125 * Get a cached contact. Note that the returned #EContact will be
126 * newly created, and must be unreffed by the caller when no longer
129 * Return value: A cached #EContact, or %NULL if @uid is not cached.
132 e_book_backend_db_cache_get_contact (DB *db, const char *uid)
134 DBT uid_dbt, vcard_dbt;
136 EContact *contact = NULL;
138 g_return_val_if_fail (uid != NULL, NULL);
140 string_to_dbt (uid, &uid_dbt);
141 memset (&vcard_dbt, 0 , sizeof(vcard_dbt));
142 vcard_dbt.flags = DB_DBT_MALLOC;
144 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt,0);
146 g_warning ("db->get failed with %d", db_error);
150 contact = e_contact_new_from_vcard ((const char *)vcard_dbt.data);
151 g_free (vcard_dbt.data);
156 * e_book_backend_db_cache_add_contact:
158 * @contact: an #EContact
160 * Adds @contact to @cache.
162 * Return value: %TRUE if the contact was cached successfully, %FALSE otherwise.
165 e_book_backend_db_cache_add_contact (DB *db,
168 DBT uid_dbt, vcard_dbt;
173 uid = e_contact_get_const (contact, E_CONTACT_UID);
176 printf("name:%s, email:%s\n",
177 (char*)e_contact_get (contact, E_CONTACT_GIVEN_NAME),
178 (char*)e_contact_get (contact, E_CONTACT_EMAIL_1));
181 string_to_dbt (uid, &uid_dbt);
183 vcard_str = e_vcard_to_string (E_VCARD(contact), EVC_FORMAT_VCARD_30);
184 string_to_dbt (vcard_str, &vcard_dbt);
186 //db_error = db->del (db, NULL, &uid_dbt, 0);
187 db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
192 g_warning ("db->put failed with %d", db_error);
200 * e_book_backend_db_cache_remove_contact:
202 * @uid: a unique contact ID
204 * Removes the contact identified by @uid from @cache.
206 * Return value: %TRUE if the contact was found and removed, %FALSE otherwise.
209 e_book_backend_db_cache_remove_contact (DB *db,
216 g_return_val_if_fail (uid != NULL, FALSE);
218 string_to_dbt (uid, &uid_dbt);
219 db_error = db->del (db, NULL, &uid_dbt, 0);
222 g_warning ("db->del failed with %d", db_error);
231 * e_book_backend_db_cache_check_contact:
233 * @uid: a unique contact ID
235 * Checks if the contact identified by @uid exists in @cache.
237 * Return value: %TRUE if the cache contains the contact, %FALSE otherwise.
240 e_book_backend_db_cache_check_contact (DB *db, const char *uid)
242 DBT uid_dbt, vcard_dbt;
245 g_return_val_if_fail (uid != NULL, FALSE);
247 string_to_dbt (uid, &uid_dbt);
248 memset (&vcard_dbt, 0 , sizeof(vcard_dbt));
249 vcard_dbt.flags = DB_DBT_MALLOC;
251 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt,0);
255 free (vcard_dbt.data);
261 * e_book_backend_db_cache_get_contacts:
263 * @query: an s-expression
265 * Returns a list of #EContact elements from @cache matching @query.
266 * When done with the list, the caller must unref the contacts and
269 * Return value: A #GList of pointers to #EContact.
272 e_book_backend_db_cache_get_contacts (DB *db, const char *query)
275 DBT uid_dbt, vcard_dbt;
278 EBookBackendSExp *sexp = NULL;
282 sexp = e_book_backend_sexp_new (query);
287 db_error = db->cursor (db, NULL, &dbc, 0);
289 g_warning ("db->cursor failed with %d", db_error);
293 memset(&vcard_dbt, 0 , sizeof(vcard_dbt));
294 memset(&uid_dbt, 0, sizeof(uid_dbt));
295 db_error = dbc->c_get(dbc, &uid_dbt, &vcard_dbt, DB_FIRST);
297 while(db_error == 0) {
298 if (vcard_dbt.data && !strncmp (vcard_dbt.data, "BEGIN:VCARD", 11)) {
299 contact = e_contact_new_from_vcard (vcard_dbt.data);
301 if (e_book_backend_sexp_match_contact(sexp, contact))
302 list = g_list_prepend (list, contact);
304 g_object_unref (contact);
306 db_error = dbc->c_get (dbc, &uid_dbt, &vcard_dbt, DB_NEXT);
309 db_error = dbc->c_close (dbc);
311 g_warning ("db->c_close failed with %d", db_error);
314 g_object_unref (sexp);
316 return g_list_reverse (list);
320 * e_book_backend_db_cache_search:
321 * @backend: an #EBookBackend
322 * @query: an s-expression
324 * Returns an array of pointers to unique contact ID strings for contacts
325 * in @cache matching @query. When done with the array, the caller must
326 * free the ID strings and the array.
328 * Return value: A #GPtrArray of pointers to contact ID strings.
331 e_book_backend_db_cache_search (DB *db, const char *query)
333 GList *matching_contacts, *temp;
334 GPtrArray *ptr_array;
336 matching_contacts = e_book_backend_db_cache_get_contacts (db, query);
337 ptr_array = g_ptr_array_new ();
339 temp = matching_contacts;
340 for (; matching_contacts != NULL; matching_contacts = g_list_next (matching_contacts)) {
341 g_ptr_array_add (ptr_array, e_contact_get (matching_contacts->data, E_CONTACT_UID));
342 g_object_unref (matching_contacts->data);
350 * e_book_backend_db_cache_exists:
351 * @uri: URI for the cache
353 * Checks if an #EBookBackendCache exists at @uri.
355 * Return value: %TRUE if cache exists, %FALSE if not.
358 e_book_backend_db_cache_exists (const char *uri)
361 gboolean exists = FALSE;
362 file_name = get_filename_from_uri (uri);
364 if (file_name && g_file_test (file_name, G_FILE_TEST_EXISTS))
373 * e_book_backend_db_cache_set_populated:
374 * @backend: an #EBookBackend
376 * Flags @cache as being populated - that is, it is up-to-date on the
377 * contents of the book it's caching.
380 e_book_backend_db_cache_set_populated (DB *db)
382 DBT uid_dbt, vcard_dbt;
385 string_to_dbt ("populated", &uid_dbt);
386 string_to_dbt ("TRUE", &vcard_dbt);
387 db_error = db->put (db, NULL, &uid_dbt, &vcard_dbt, 0);
389 g_warning ("db->put failed with %d", db_error);
395 * e_book_backend_cache_is_populated:
398 * Checks if @cache is populated.
400 * Return value: %TRUE if @cache is populated, %FALSE otherwise.
403 e_book_backend_db_cache_is_populated (DB *db)
405 DBT uid_dbt, vcard_dbt;
408 string_to_dbt ("populated", &uid_dbt);
409 memset(&vcard_dbt, 0, sizeof(vcard_dbt));
410 vcard_dbt.flags = DB_DBT_MALLOC;
412 db_error = db->get (db, NULL, &uid_dbt, &vcard_dbt, 0);
417 free(vcard_dbt.data);