From edafd33318781d2fc9badedc5c0a90287e4261f9 Mon Sep 17 00:00:00 2001 From: Adrien Bustany Date: Wed, 18 Jul 2012 21:34:35 +0300 Subject: [PATCH] [PATCH 7/7] go: Bind notmuch_thread_t functions --- 7b/ba31382bba6ad093dcfb7235278e7f7a48acf6 | 337 ++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 7b/ba31382bba6ad093dcfb7235278e7f7a48acf6 diff --git a/7b/ba31382bba6ad093dcfb7235278e7f7a48acf6 b/7b/ba31382bba6ad093dcfb7235278e7f7a48acf6 new file mode 100644 index 000000000..680be69a8 --- /dev/null +++ b/7b/ba31382bba6ad093dcfb7235278e7f7a48acf6 @@ -0,0 +1,337 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by olra.theworths.org (Postfix) with ESMTP id 5683F431FDB + for ; Wed, 18 Jul 2012 11:41:09 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: 0 +X-Spam-Level: +X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] + autolearn=disabled +Received: from olra.theworths.org ([127.0.0.1]) + by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id OV4D8BBF1Od8 for ; + Wed, 18 Jul 2012 11:41:06 -0700 (PDT) +Received: from mail.bustany.org (bustany.org [176.31.244.208]) + by olra.theworths.org (Postfix) with ESMTP id 8063D431FC3 + for ; Wed, 18 Jul 2012 11:41:05 -0700 (PDT) +Received: from localhost.localdomain (91-158-2-79.elisa-laajakaista.fi + [91.158.2.79]) + by mail.bustany.org (Postfix) with ESMTPSA id D26D51400EE + for ; Wed, 18 Jul 2012 20:37:09 +0200 (CEST) +From: Adrien Bustany +To: notmuch@notmuchmail.org +Subject: [PATCH 7/7] go: Bind notmuch_thread_t functions +Date: Wed, 18 Jul 2012 21:34:35 +0300 +Message-Id: <1342636475-16057-8-git-send-email-adrien@bustany.org> +X-Mailer: git-send-email 1.7.7.6 +In-Reply-To: <1342636475-16057-1-git-send-email-adrien@bustany.org> +References: <1342636475-16057-1-git-send-email-adrien@bustany.org> +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.13 +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: Wed, 18 Jul 2012 18:41:09 -0000 + +--- + bindings/go/src/notmuch/notmuch.go | 253 +++++++++++++++++++++++++++++++++++- + 1 files changed, 252 insertions(+), 1 deletions(-) + +diff --git a/bindings/go/src/notmuch/notmuch.go b/bindings/go/src/notmuch/notmuch.go +index be4cb8c..f667dbb 100644 +--- a/bindings/go/src/notmuch/notmuch.go ++++ b/bindings/go/src/notmuch/notmuch.go +@@ -12,6 +12,8 @@ package notmuch + */ + import "C" + import "runtime" ++import "strings" ++import "time" + import "unsafe" + + // Status codes used for the return values of most functions +@@ -700,7 +702,20 @@ func (self *Query) CountMessages() uint { + return uint(C.notmuch_query_count_messages(self.query)) + } + +-// TODO: wrap threads and thread ++/* Return the number of threads matching a search. ++ * ++ * This function performs a search and returns the number of unique thread IDs ++ * in the matching messages. This is the same as number of threads matching a ++ * search. ++ * ++ * Note that this is a significantly heavier operation than ++ * notmuch_query_count_messages(). ++ * ++ * If an error occurs, this function may return 0. ++ */ ++func (self *Query) CountThreads() uint { ++ return uint(C.notmuch_query_count_threads(self.query)) ++} + + /* Is the given 'threads' iterator pointing at a valid thread. + * +@@ -722,6 +737,45 @@ func (self *Threads) Valid() bool { + return true + } + ++/* Get the current thread from 'threads' as a notmuch_thread_t. ++ * ++ * Note: The returned thread belongs to 'threads' and has a lifetime ++ * identical to it (and the query to which it belongs). ++ * ++ * See the documentation of notmuch_query_search_threads for example ++ * code showing how to iterate over a notmuch_threads_t object. ++ * ++ * If an out-of-memory situation occurs, this function will return ++ * NULL. ++ */ ++func (self *Threads) Get() *Thread { ++ if self.threads == nil { ++ return nil ++ } ++ thread := C.notmuch_threads_get(self.threads) ++ if thread == nil { ++ return nil ++ } ++ return createThread(thread, self) ++} ++ ++/* Move the 'threads' iterator to the next thread. ++ * ++ * If 'threads' is already pointing at the last thread then the ++ * iterator will be moved to a point just beyond that last thread, ++ * (where notmuch_threads_valid will return FALSE and ++ * notmuch_threads_get will return NULL). ++ * ++ * See the documentation of notmuch_query_search_threads for example ++ * code showing how to iterate over a notmuch_threads_t object. ++ */ ++func (self *Threads) MoveToNext() { ++ if self.threads == nil { ++ return ++ } ++ C.notmuch_threads_move_to_next(self.threads) ++} ++ + /* Destroy a notmuch_threads_t object. + * + * It's not strictly necessary to call this function. All memory from +@@ -735,6 +789,203 @@ func (self *Threads) Destroy() { + } + } + ++/* Get the thread ID of 'thread'. ++ * ++ * The returned string belongs to 'thread' and as such, should not be ++ * modified by the caller and will only be valid for as long as the ++ * thread is valid, (which is until notmuch_thread_destroy or until ++ * the query from which it derived is destroyed). ++ */ ++func (self *Thread) GetThreadId() string { ++ if self.thread == nil { ++ return "" ++ } ++ id := C.notmuch_thread_get_thread_id(self.thread) ++ ++ if id == nil { ++ return "" ++ } ++ ++ return C.GoString(id) ++} ++ ++/* Get the total number of messages in 'thread'. ++ * ++ * This count consists of all messages in the database belonging to ++ * this thread. Contrast with notmuch_thread_get_matched_messages() . ++ */ ++func (self *Thread) GetTotalMessages() int { ++ if self.thread == nil { ++ return 0 ++ } ++ return int(C.notmuch_thread_get_total_messages(self.thread)) ++} ++ ++/* Get a notmuch_messages_t iterator for the top-level messages in ++ * 'thread'. ++ * ++ * This iterator will not necessarily iterate over all of the messages ++ * in the thread. It will only iterate over the messages in the thread ++ * which are not replies to other messages in the thread. ++ * ++ * To iterate over all messages in the thread, the caller will need to ++ * iterate over the result of notmuch_message_get_replies for each ++ * top-level message (and do that recursively for the resulting ++ * messages, etc.). ++ */ ++func (self *Thread) GetToplevelMessages() *Messages { ++ if self.thread == nil { ++ return nil ++ } ++ msgs := C.notmuch_thread_get_toplevel_messages(self.thread) ++ if msgs == nil { ++ return nil ++ } ++ return createMessages(msgs, self) ++} ++ ++/* Get a notmuch_messages_t iterator for the top-level messages in ++ * 'thread'. ++ * ++ * This iterator will not necessarily iterate over all of the messages ++ * in the thread. It will only iterate over the messages in the thread ++ * which are not replies to other messages in the thread. ++ * ++ * To iterate over all messages in the thread, the caller will need to ++ * iterate over the result of notmuch_message_get_replies for each ++ * top-level message (and do that recursively for the resulting ++ * messages, etc.). ++ */ ++func (self *Thread) GetMatchedMessages() int { ++ if self.thread == nil { ++ return 0 ++ } ++ return int(C.notmuch_thread_get_matched_messages(self.thread)) ++} ++ ++/* Get a notmuch_messages_t iterator for the top-level messages in ++ * 'thread'. ++ * ++ * This iterator will not necessarily iterate over all of the messages ++ * in the thread. It will only iterate over the messages in the thread ++ * which are not replies to other messages in the thread. ++ * ++ * To iterate over all messages in the thread, the caller will need to ++ * iterate over the result of notmuch_message_get_replies for each ++ * top-level message (and do that recursively for the resulting ++ * messages, etc.). ++ */ ++func (self *Thread) GetAuthors() []string { ++ if self.thread == nil { ++ return make([]string, 0) ++ } ++ authors_str := C.notmuch_thread_get_authors(self.thread) ++ ++ if authors_str == nil { ++ return make([]string, 0) ++ } ++ ++ return strings.Split(C.GoString(authors_str), ", ") ++} ++ ++/* Get the subject of 'thread' ++ * ++ * The subject is taken from the first message (according to the query ++ * order---see notmuch_query_set_sort) in the query results that ++ * belongs to this thread. ++ * ++ * The returned string belongs to 'thread' and as such, should not be ++ * modified by the caller and will only be valid for as long as the ++ * thread is valid, (which is until notmuch_thread_destroy or until ++ * the query from which it derived is destroyed). ++ */ ++func (self *Thread) GetSubject() string { ++ if self.thread == nil { ++ return "" ++ } ++ subject := C.notmuch_thread_get_subject(self.thread) ++ ++ if subject == nil { ++ return "" ++ } ++ ++ return C.GoString(subject) ++} ++ ++/* Get the date of the oldest message in 'thread' as a time_t value. ++ */ ++func (self *Thread) GetOldestDate() time.Time { ++ if self.thread == nil { ++ return time.Unix(0, 0) ++ } ++ return time.Unix(int64(C.notmuch_thread_get_oldest_date(self.thread)), 0) ++} ++ ++/* Get the date of the newest message in 'thread' as a time_t value. ++ */ ++func (self *Thread) GetNewestDate() time.Time { ++ if self.thread == nil { ++ return time.Unix(0, 0) ++ } ++ return time.Unix(int64(C.notmuch_thread_get_oldest_date(self.thread)), 0) ++} ++ ++/* Get the tags for 'thread', returning a notmuch_tags_t object which ++ * can be used to iterate over all tags. ++ * ++ * Note: In the Notmuch database, tags are stored on individual ++ * messages, not on threads. So the tags returned here will be all ++ * tags of the messages which matched the search and which belong to ++ * this thread. ++ * ++ * The tags object is owned by the thread and as such, will only be ++ * valid for as long as the thread is valid, (for example, until ++ * notmuch_thread_destroy or until the query from which it derived is ++ * destroyed). ++ * ++ * Typical usage might be: ++ * ++ * notmuch_thread_t *thread; ++ * notmuch_tags_t *tags; ++ * const char *tag; ++ * ++ * thread = notmuch_threads_get (threads); ++ * ++ * for (tags = notmuch_thread_get_tags (thread); ++ * notmuch_tags_valid (tags); ++ * notmuch_result_move_to_next (tags)) ++ * { ++ * tag = notmuch_tags_get (tags); ++ * .... ++ * } ++ * ++ * notmuch_thread_destroy (thread); ++ * ++ * Note that there's no explicit destructor needed for the ++ * notmuch_tags_t object. (For consistency, we do provide a ++ * notmuch_tags_destroy function, but there's no good reason to call ++ * it if the message is about to be destroyed). ++ */ ++func (self *Thread) GetTags() *Tags { ++ if self.thread == nil { ++ return nil ++ } ++ tags := C.notmuch_thread_get_tags(self.thread) ++ if tags == nil { ++ return nil ++ } ++ return createTags(tags, self) ++} ++ ++/* Destroy a notmuch_thread_t object. */ ++func (self *Thread) Destroy() { ++ if self.thread == nil { ++ return ++ } ++ C.notmuch_thread_destroy(self.thread) ++ self.thread = nil ++} ++ + /* Is the given 'messages' iterator pointing at a valid message. + * + * When this function returns TRUE, notmuch_messages_get will return a +-- +1.7.7.6 + -- 2.26.2