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