[Evolution-hackers] [PATCH 5/6] EBookSqlite: Add support for storing x509Cert in a boolean summary field



We don't actually care about summarising the *data*; merely indicating
the *presence* of the field is sufficient. With the new evolution-pkcs11
module, the 'exists(x509Cert)' query is going to get very hot...

This halves the time it takes to query the Intel global addressbook,
with almost quarter of a million entries of whom about 5% have
certificates listed. Adding an index on the field would probably make it
even faster, if it can be used appropriately. And if I knew how to do it.
---
 addressbook/libedata-book/e-book-sqlite.c | 49 ++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/addressbook/libedata-book/e-book-sqlite.c b/addressbook/libedata-book/e-book-sqlite.c
index 13a4843..09eceff 100644
--- a/addressbook/libedata-book/e-book-sqlite.c
+++ b/addressbook/libedata-book/e-book-sqlite.c
@@ -449,7 +449,7 @@ column_info_new (SummaryField *field,
        if (!info->type) {
                if (field->type == G_TYPE_STRING)
                        info->type = "TEXT";
-               else if (field->type == G_TYPE_BOOLEAN)
+               else if (field->type == G_TYPE_BOOLEAN || field->type == E_TYPE_CONTACT_CERT)
                        info->type = "INTEGER";
                else if (field->type == E_TYPE_CONTACT_ATTR_LIST)
                        info->type = "TEXT";
@@ -551,6 +551,7 @@ summary_field_append (GArray *array,
 
        if (type != G_TYPE_STRING &&
            type != G_TYPE_BOOLEAN &&
+           type != E_TYPE_CONTACT_CERT &&
            type != E_TYPE_CONTACT_ATTR_LIST) {
                EBSQL_SET_ERROR (
                        error, E_BOOK_SQLITE_ERROR_UNSUPPORTED_FIELD,
@@ -645,6 +646,7 @@ summary_field_list_columns (SummaryField *field,
        g_return_val_if_fail (
                field->type == G_TYPE_STRING ||
                field->type == G_TYPE_BOOLEAN ||
+               field->type == E_TYPE_CONTACT_CERT ||
                field->type == E_TYPE_CONTACT_ATTR_LIST,
                NULL);
 
@@ -662,13 +664,15 @@ summary_field_list_columns (SummaryField *field,
        }
 
        /* Suffix match column */
-       if (field->type != G_TYPE_BOOLEAN && (field->index & INDEX_FLAG (SUFFIX)) != 0) {
+       if (field->type != G_TYPE_BOOLEAN && field->type != E_TYPE_CONTACT_CERT &&
+           (field->index & INDEX_FLAG (SUFFIX)) != 0) {
                info = column_info_new (field, folderid, EBSQL_SUFFIX_REVERSE, "TEXT", NULL, "RINDEX");
                columns = g_slist_prepend (columns, info);
        }
 
        /* Phone match columns */
-       if (field->type != G_TYPE_BOOLEAN && (field->index & INDEX_FLAG (PHONE)) != 0) {
+       if (field->type != G_TYPE_BOOLEAN && field->type != E_TYPE_CONTACT_CERT &&
+           (field->index & INDEX_FLAG (PHONE)) != 0) {
 
                /* One indexed column for storing the national number */
                info = column_info_new (field, folderid, EBSQL_SUFFIX_PHONE, "TEXT", NULL, "PINDEX");
@@ -3450,7 +3454,8 @@ ebsql_prepare_insert (EBookSqlite *ebsql,
                                g_string_append (string, ", ");
                }
 
-               if (field->type == G_TYPE_STRING || field->type == G_TYPE_BOOLEAN) {
+               if (field->type == G_TYPE_STRING || field->type == G_TYPE_BOOLEAN ||
+                   field->type == E_TYPE_CONTACT_CERT) {
 
                        g_string_append_c (string, ':');
                        g_string_append (string, field->dbname);
@@ -3626,6 +3631,15 @@ ebsql_run_insert (EBookSqlite *ebsql,
                        val = e_contact_get (contact, field->field_id) ? TRUE : FALSE;
 
                        ret = sqlite3_bind_int (stmt, param_idx++, val ? 1 : 0);
+               } else if (field->type == E_TYPE_CONTACT_CERT) {
+                       EContactCert *cert = NULL;
+
+                       cert = e_contact_get (contact, field->field_id);
+
+                       /* We don't actually store the cert; only a boolean to indicate
+                        * that is *has* a cert. */
+                       ret = sqlite3_bind_int (stmt, param_idx++, cert ? 1 : 0);
+                       e_contact_cert_free (cert);
                } else if (field->type != E_TYPE_CONTACT_ATTR_LIST)
                        g_warn_if_reached ();
        }
@@ -4536,6 +4550,17 @@ query_preflight_check (PreflightContext *context,
 
                switch (field_test) {
                case E_BOOK_QUERY_IS:
+                       if (test->field && test->field->type == E_TYPE_CONTACT_CERT) {
+                       no_cert_content:
+                               context->status = MAX (context->status, PREFLIGHT_NOT_SUMMARIZED);
+                               EBSQL_NOTE (
+                                       PREFLIGHT,
+                                       g_printerr (
+                                               "PREFLIGHT CHECK: "
+                                               "Refusing content check on X.509 cert field '%s', new status: 
%s\n",
+                                               EBSQL_FIELD_ID_STR (test->field_id),
+                                               EBSQL_STATUS_STR (context->status)));
+                       }
                        break;
 
                case BOOK_QUERY_EXISTS:
@@ -4545,11 +4570,15 @@ query_preflight_check (PreflightContext *context,
                case E_BOOK_QUERY_REGEX_NORMAL:
 
                        /* All of these queries can only apply to string fields,
-                        * or fields which hold multiple strings 
+                        * or fields which hold multiple strings. Except for
+                        * BOOK_QUERY_EXISTS which can be used for the cert field.
                         */
                        if (test->field) {
-                               if (test->field->type != G_TYPE_STRING &&
-                                   test->field->type != E_TYPE_CONTACT_ATTR_LIST) {
+                               if (test->field->type == E_TYPE_CONTACT_CERT) {
+                                       if (field_test != BOOK_QUERY_EXISTS)
+                                               goto no_cert_content;
+                               } else if (test->field->type != G_TYPE_STRING &&
+                                          test->field->type != E_TYPE_CONTACT_ATTR_LIST) {
                                        context->status = MAX (context->status, PREFLIGHT_INVALID);
                                        EBSQL_NOTE (
                                                PREFLIGHT,
@@ -5068,7 +5097,11 @@ field_test_query_exists (EBookSqlite *ebsql,
        SummaryField *field = test->field;
 
        ebsql_string_append_column (string, field, NULL);
-       ebsql_string_append_printf (string, " IS NOT NULL");
+
+       if (test->field->type == E_TYPE_CONTACT_CERT)
+               ebsql_string_append_printf (string, " IS NOT '0'");
+       else
+               ebsql_string_append_printf (string, " IS NOT NULL");
 }
 
 /* Lookup table for field test generators per EBookQueryTest,
-- 
1.9.3


-- 
David Woodhouse                            Open Source Technology Centre
David Woodhouse intel com                              Intel Corporation

Attachment: smime.p7s
Description: S/MIME cryptographic signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]