From cf9536db2b049bd6a0c8f805acfa122ca695f678 Mon Sep 17 00:00:00 2001 From: Chris Toshok Date: Wed, 12 Apr 2000 19:06:04 +0000 Subject: rework this function to use a table mapping search field names to vcard * addressbook/backend/pas/pas-backend-file.c (entry_compare): rework this function to use a table mapping search field names to vcard properties and extra information (such as whether or not the property is a list.) * addressbook/backend/pas/pas-backend-ldap.c (construct_email_list): new function, to build the ECardList for email addresses. (construct_phone_list): new function, to build the ECardList for phone numbers. (pas_backend_ldap_search): use a table mapping ldap attributes to ecard properties, and use the special list construction functions if the property calls for it. general cleanup. added a comment about not calling ber_free if there was a decoding error. svn path=/trunk/; revision=2411 --- addressbook/backend/pas/pas-backend-file.c | 76 ++++++++++-------- addressbook/backend/pas/pas-backend-ldap.c | 121 +++++++++++++++++++++-------- 2 files changed, 132 insertions(+), 65 deletions(-) (limited to 'addressbook/backend/pas') diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c index c0d8b49113..e7ed1925f0 100644 --- a/addressbook/backend/pas/pas-backend-file.c +++ b/addressbook/backend/pas/pas-backend-file.c @@ -153,24 +153,6 @@ pas_backend_file_create_unique_id (char *vcard) return g_strdup_printf ("pas-id-%08lX%08X", time(NULL), c++); } -static char * -get_e_card_string_prop (ECard *ecard, const char *propname) -{ - char *prop = NULL; - - if (!strcasecmp(propname, "full_name")) - gtk_object_get(GTK_OBJECT(ecard), - "full_name", &prop, NULL); - else if (!strcasecmp(propname, "url")) - gtk_object_get(GTK_OBJECT(ecard), - "url", &prop, NULL); - else if (!strcasecmp(propname, "mailer")) - gtk_object_get(GTK_OBJECT(ecard), - "mailer", &prop, NULL); - - return prop; -} - static gboolean compare_email (ECard *ecard, const char *str, char *(*compare)(const char*, const char*)) @@ -237,6 +219,27 @@ compare_address (ECard *ecard, const char *str, return FALSE; } +static struct prop_info { + const char *query_prop; + const char *ecard_prop; +#define PROP_TYPE_NORMAL 0x01 +#define PROP_TYPE_LIST 0x02 +#define PROP_TYPE_LISTITEM 0x03 + int prop_type; + gboolean (*list_compare)(ECard *ecard, const char *str, + char *(*compare)(const char*, const char*)); + +} prop_info_table[] = { + /* query prop, ecard prop, type, list compare function */ + { "full_name", "full_name", PROP_TYPE_NORMAL, NULL }, + { "url", "url", PROP_TYPE_NORMAL, NULL }, + { "mailer", "mailer", PROP_TYPE_NORMAL, NULL }, + { "email", "email", PROP_TYPE_LIST, compare_email }, + { "phone", "phone", PROP_TYPE_LIST, compare_phone }, + { "address", "address", PROP_TYPE_LIST, compare_address }, +}; +static int num_prop_infos = sizeof(prop_info_table) / sizeof(prop_info_table[0]); + static ESExpResult * entry_compare(PASBackendFileSearchContext *ctx, struct _ESExp *f, int argc, struct _ESExpResult **argv, @@ -248,26 +251,35 @@ entry_compare(PASBackendFileSearchContext *ctx, struct _ESExp *f, if (argc == 2 && argv[0]->type == ESEXP_RES_STRING && argv[1]->type == ESEXP_RES_STRING) { - char *propname, *prop = NULL; + char *propname; + struct prop_info *info = NULL; + int i; propname = argv[0]->value.string; - prop = get_e_card_string_prop (ctx->ecard, propname); - - if (prop) { - if (compare(prop, argv[1]->value.string)) { - truth = TRUE; + for (i = 0; i < num_prop_infos; i ++) { + if (!strcmp (prop_info_table[i].query_prop, propname)) { + info = &prop_info_table[i]; + break; } } - else{ - if (!strcmp(propname, "email")) { - truth = compare_email (ctx->ecard, argv[1]->value.string, compare); - } - else if (!strcasecmp(propname, "phone")) { - truth = compare_phone (ctx->ecard, argv[1]->value.string, compare); + + if (info) { + if (info->prop_type == PROP_TYPE_NORMAL) { + char *prop = NULL; + /* searches where the query's property + maps directly to an ecard property */ + + gtk_object_get(GTK_OBJECT(ctx->ecard), + info->ecard_prop, &prop, NULL); + + if (prop && compare(prop, argv[1]->value.string)) { + truth = TRUE; + } } - else if (!strcasecmp(propname, "address")) { - truth = compare_address (ctx->ecard, argv[1]->value.string, compare); + else if (info->prop_type == PROP_TYPE_LIST) { + /* the special searches that match any of the list elements */ + truth = info->list_compare (ctx->ecard, argv[1]->value.string, compare); } } diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c index 61396d257d..419905dab4 100644 --- a/addressbook/backend/pas/pas-backend-ldap.c +++ b/addressbook/backend/pas/pas-backend-ldap.c @@ -21,7 +21,8 @@ #include #define LDAP_MAX_SEARCH_RESPONSES 500 -#define CARDS_PER_VIEW_NOTIFICATION 10 + +static gchar *map_e_card_prop_to_ldap(gchar *e_card_prop); static PASBackendClass *pas_backend_ldap_parent_class; typedef struct _PASBackendLDAPCursorPrivate PASBackendLDAPCursorPrivate; @@ -283,21 +284,6 @@ pas_backend_ldap_process_get_cursor (PASBackend *backend, cursor); } -static gchar * -map_e_card_prop_to_ldap(gchar *e_card_prop) -{ - if (!strcmp(e_card_prop, "full_name")) return "cn"; - else if (!strcmp(e_card_prop, "email")) return "mail"; - else return NULL; -} - -static gchar * -map_ldap_to_e_card_prop(gchar *ldap_attr) -{ - if (!strcmp(ldap_attr, "cn")) return "full_name"; - else return NULL; -} - static ESExpResult * func_and(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data) { @@ -562,6 +548,67 @@ pas_backend_ldap_build_query (gchar *query) return retval; } +static void +construct_email_list(ECard *card, const char *prop, char **values) +{ + ECardList *list; + int i; + + gtk_object_get(GTK_OBJECT(card), + "email", &list, + NULL); + + for (i = 0; values[i]; i ++) { + e_card_list_append(list, values[i]); + } +} + +static void +construct_phone_list(ECard *card, const char *prop, char **values) +{ + ECardList *list; + int i; + + gtk_object_get(GTK_OBJECT(card), + "phone", &list, + NULL); + + for (i = 0; values[i]; i ++) { + ECardPhone *phone_entry = g_new0(ECardPhone, 1); + phone_entry->number = g_strdup (values[i]); + e_card_list_append(list, phone_entry); + } +} + +struct prop_info { + const char *query_prop; + const char *ldap_attr; +#define PROP_TYPE_NORMAL 0x01 +#define PROP_TYPE_LIST 0x02 +#define PROP_TYPE_LISTITEM 0x03 + int prop_type; + void (*construct_list_func)(ECard *card, const char *prop, char **values); +} prop_info_table[] = { + /* query prop, ldap attr, type, list construct function */ + { "full_name", "cn", PROP_TYPE_NORMAL, NULL }, + { "email", "mail", PROP_TYPE_LIST, construct_email_list }, + { "phone", "telephoneNumber", PROP_TYPE_LIST, construct_phone_list } +}; + +static int num_prop_infos = sizeof(prop_info_table) / sizeof(prop_info_table[0]); + +static gchar * +map_e_card_prop_to_ldap(gchar *e_card_prop) +{ + int i; + + for (i = 0; i < num_prop_infos; i ++) + if (!strcmp (e_card_prop, prop_info_table[i].query_prop)) + return prop_info_table[i].ldap_attr; + + return NULL; +} + static void pas_backend_ldap_search (PASBackendLDAP *bl, PASBook *book, @@ -594,47 +641,55 @@ pas_backend_ldap_search (PASBackendLDAP *bl, while (NULL != e) { ECard *card = E_CARD(gtk_type_new(e_card_get_type())); char *dn = ldap_get_dn(ldap, e); - char *attr, *prop; + char *attr; BerElement *ber = NULL; - int card_count = 0; e_card_set_id (card, dn); - /* XXX needs a bit of work here */ for (attr = ldap_first_attribute (ldap, e, &ber); attr; attr = ldap_next_attribute (ldap, e, ber)) { - prop = map_ldap_to_e_card_prop (attr); - - if (prop) { + int i; + struct prop_info *info = NULL; + + for (i = 0; i < num_prop_infos; i ++) + if (!strcmp (attr, prop_info_table[i].ldap_attr)) + info = &prop_info_table[i]; + + if (info) { char **values; values = ldap_get_values (ldap, e, attr); - gtk_object_set(GTK_OBJECT(card), prop, values[0], NULL); + if (info->prop_type == PROP_TYPE_NORMAL) { + /* if it's a normal property just set the string */ + gtk_object_set(GTK_OBJECT(card), + info->query_prop, values[0], NULL); + + } + else if (info->prop_type == PROP_TYPE_LIST) { + /* if it's a list call the construction function, + which calls gtk_object_set to set the property */ + info->construct_list_func(card, + info->query_prop, + values); + } ldap_value_free (values); } } + /* if ldap->ld_errno == LDAP_DECODING_ERROR there was an + error decoding an attribute, and we shouldn't free ber, + since the ldap library already did it. */ if (ldap->ld_errno != LDAP_DECODING_ERROR && ber) ber_free (ber, 0); cards = g_list_append(cards, e_card_get_vcard(card)); - card_count ++; - if (card_count == CARDS_PER_VIEW_NOTIFICATION) { - card_count = 0; - pas_book_view_notify_add (view->book_view, cards); - - g_list_foreach (cards, (GFunc)g_free, NULL); - g_list_free (cards); - cards = NULL; - } gtk_object_unref (GTK_OBJECT(card)); e = ldap_next_entry(ldap, e); } - /* send any straglers */ if (cards) { pas_book_view_notify_add (view->book_view, cards); -- cgit