From c62ac3a7735c0d5629f4c6cdef462f39a7edc24e Mon Sep 17 00:00:00 2001 From: David Bremner Date: Sun, 10 Jan 2016 22:51:34 +2000 Subject: [PATCH] [WIP patch 2/9] lib: notmuch_metadata_t: iterators for metadata --- fa/5a972e9249b14821bd44acd7e1599c5ec0014d | 188 ++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 fa/5a972e9249b14821bd44acd7e1599c5ec0014d diff --git a/fa/5a972e9249b14821bd44acd7e1599c5ec0014d b/fa/5a972e9249b14821bd44acd7e1599c5ec0014d new file mode 100644 index 000000000..18989d3b1 --- /dev/null +++ b/fa/5a972e9249b14821bd44acd7e1599c5ec0014d @@ -0,0 +1,188 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by arlo.cworth.org (Postfix) with ESMTP id 5A92B6DE02C9 + for ; Sat, 9 Jan 2016 18:51:56 -0800 (PST) +X-Virus-Scanned: Debian amavisd-new at cworth.org +X-Spam-Flag: NO +X-Spam-Score: -0.311 +X-Spam-Level: +X-Spam-Status: No, score=-0.311 tagged_above=-999 required=5 tests=[AWL=0.240, + RP_MATCHES_RCVD=-0.55, SPF_PASS=-0.001] autolearn=disabled +Received: from arlo.cworth.org ([127.0.0.1]) + by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id BoS80j-V-ETt for ; + Sat, 9 Jan 2016 18:51:53 -0800 (PST) +Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) + by arlo.cworth.org (Postfix) with ESMTPS id 79B206DE028A + for ; Sat, 9 Jan 2016 18:51:53 -0800 (PST) +Received: from remotemail by fethera.tethera.net with local (Exim 4.84) + (envelope-from ) + id 1aI66Y-0007Cy-PY; Sat, 09 Jan 2016 21:51:42 -0500 +Received: (nullmailer pid 29640 invoked by uid 1000); + Sun, 10 Jan 2016 02:51:47 -0000 +From: David Bremner +To: notmuch@notmuchmail.org +Subject: [WIP patch 2/9] lib: notmuch_metadata_t: iterators for metadata +Date: Sat, 9 Jan 2016 22:51:34 -0400 +Message-Id: <1452394301-29499-3-git-send-email-david@tethera.net> +X-Mailer: git-send-email 2.6.4 +In-Reply-To: <1452394301-29499-1-git-send-email-david@tethera.net> +References: <1452394301-29499-1-git-send-email-david@tethera.net> +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.20 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Sun, 10 Jan 2016 02:51:56 -0000 + +The rough idea is to give a C interface to the Xapian::TermIterator class. +--- + lib/metadata.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ + lib/notmuch.h | 12 ++++++++++ + test/T590-metadata.sh | 15 ++++++++++++ + 3 files changed, 90 insertions(+) + +diff --git a/lib/metadata.cc b/lib/metadata.cc +index a068ed1..5d319c5 100644 +--- a/lib/metadata.cc ++++ b/lib/metadata.cc +@@ -22,6 +22,17 @@ + #include "notmuch-private.h" + #include "database-private.h" + ++struct _notmuch_metadata { ++ notmuch_database_t *notmuch; ++ Xapian::TermIterator *iterator; ++ notmuch_metadata_class_t mclass; ++}; ++ ++static int ++_notmuch_metadata_destroy (notmuch_metadata_t *list) { ++ delete list->iterator; ++ return 0; ++} + static + const char * + _find_metadata_prefix (notmuch_metadata_class_t mclass) +@@ -148,3 +159,55 @@ notmuch_database_get_metadata (notmuch_database_t *notmuch, + + return NOTMUCH_STATUS_SUCCESS; + } ++ ++notmuch_status_t ++notmuch_database_get_all_metadata (notmuch_database_t *notmuch, ++ notmuch_metadata_class_t mclass, ++ notmuch_metadata_t **out) ++{ ++ notmuch_metadata_t *list = NULL; ++ notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; ++ ++ const char *prefix = _find_metadata_prefix (mclass); ++ ++ list = talloc (notmuch, notmuch_metadata_t); ++ if (!list) { ++ status = NOTMUCH_STATUS_OUT_OF_MEMORY; ++ goto DONE; ++ } ++ ++ talloc_set_destructor(list, _notmuch_metadata_destroy); ++ list->iterator = new Xapian::TermIterator; ++ list->notmuch = notmuch; ++ list->mclass = mclass; ++ ++ try { ++ ++ *list->iterator = notmuch->xapian_db->metadata_keys_begin(); ++ list->iterator->skip_to (prefix); ++ ++ } catch (const Xapian::Error &error) { ++ _notmuch_database_log (notmuch, "A Xapian exception occurred getting metadata iterator: %s.\n", ++ error.get_msg().c_str()); ++ notmuch->exception_reported = TRUE; ++ status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; ++ } ++ ++ *out = list; ++ ++ DONE: ++ if (status && list) ++ talloc_free (list); ++ ++ return status; ++} ++ ++notmuch_bool_t ++notmuch_metadata_valid (notmuch_metadata_t *metadata) ++{ ++ const char *prefix = _find_metadata_prefix (metadata->mclass); ++ if (*(metadata->iterator) == metadata->notmuch->xapian_db->metadata_keys_end()) ++ return FALSE; ++ ++ return (strncmp((**(metadata->iterator)).c_str (), prefix, strlen (prefix)) == 0); ++} +diff --git a/lib/notmuch.h b/lib/notmuch.h +index 448f405..a2b7040 100644 +--- a/lib/notmuch.h ++++ b/lib/notmuch.h +@@ -197,6 +197,7 @@ typedef struct _notmuch_message notmuch_message_t; + typedef struct _notmuch_tags notmuch_tags_t; + typedef struct _notmuch_directory notmuch_directory_t; + typedef struct _notmuch_filenames notmuch_filenames_t; ++typedef struct _notmuch_metadata notmuch_metadata_t; + #endif /* __DOXYGEN__ */ + + /** +@@ -1854,6 +1855,17 @@ notmuch_database_set_metadata (notmuch_database_t *db, notmuch_metadata_class_t + notmuch_status_t + notmuch_database_get_metadata (notmuch_database_t *db, notmuch_metadata_class_t mclass, const char *key, char **value); + ++/** ++ * get all metadata of a given class ++ */ ++notmuch_status_t ++notmuch_database_get_all_metadata (notmuch_database_t *db, notmuch_metadata_class_t mclass, notmuch_metadata_t **out); ++ ++/** ++ * Is 'metadata' iterator valid (i.e. _key, _value, _move_to_next can be called). ++ */ ++notmuch_bool_t ++notmuch_metadata_valid (notmuch_metadata_t *metadata); + /* @} */ + + NOTMUCH_END_DECLS +diff --git a/test/T590-metadata.sh b/test/T590-metadata.sh +index 29aeaa2..c36a7d7 100755 +--- a/test/T590-metadata.sh ++++ b/test/T590-metadata.sh +@@ -55,4 +55,19 @@ testkey2 = testvalue2 + EOF + test_expect_equal_file EXPECTED OUTPUT + ++test_begin_subtest "notmuch_database_get_all_metadata initially valid" ++cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ++{ ++ notmuch_metadata_t *meta; ++ RUN(notmuch_database_get_all_metadata (db, NOTMUCH_METADATA_CONFIG, &meta)); ++ printf("valid = %d\n", notmuch_metadata_valid (meta)); ++} ++EOF ++cat <<'EOF' >EXPECTED ++== stdout == ++valid = 1 ++== stderr == ++EOF ++test_expect_equal_file EXPECTED OUTPUT ++ + test_done +-- +2.6.4 + -- 2.26.2