1 Return-Path: <amdragon@mit.edu>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id B46FE429E21
\r
6 for <notmuch@notmuchmail.org>; Mon, 3 Oct 2011 10:40:51 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5
\r
12 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id d+MARKky+BqA for <notmuch@notmuchmail.org>;
\r
16 Mon, 3 Oct 2011 10:40:50 -0700 (PDT)
\r
17 Received: from dmz-mailsec-scanner-4.mit.edu (DMZ-MAILSEC-SCANNER-4.MIT.EDU
\r
19 by olra.theworths.org (Postfix) with ESMTP id 46143431FB6
\r
20 for <notmuch@notmuchmail.org>; Mon, 3 Oct 2011 10:40:50 -0700 (PDT)
\r
21 X-AuditID: 1209190f-b7f6e6d0000008df-b7-4e89f3a0facd
\r
22 Received: from mailhub-auth-1.mit.edu ( [18.9.21.35])
\r
23 by dmz-mailsec-scanner-4.mit.edu (Symantec Messaging Gateway) with SMTP
\r
24 id 27.B0.02271.0A3F98E4; Mon, 3 Oct 2011 13:40:48 -0400 (EDT)
\r
25 Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])
\r
26 by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id p93HemLv012854;
\r
27 Mon, 3 Oct 2011 13:40:48 -0400
\r
28 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])
\r
29 (authenticated bits=0)
\r
30 (User authenticated as amdragon@ATHENA.MIT.EDU)
\r
31 by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id p93Hekw5028698
\r
32 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);
\r
33 Mon, 3 Oct 2011 13:40:47 -0400 (EDT)
\r
34 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.72)
\r
35 (envelope-from <amdragon@mit.edu>)
\r
36 id 1RAmXk-0003SK-Nc; Mon, 03 Oct 2011 13:43:08 -0400
\r
37 Date: Mon, 3 Oct 2011 13:43:08 -0400
\r
38 From: Austin Clements <amdragon@MIT.EDU>
\r
39 To: Ali Polatel <polatel@gmail.com>
\r
40 Subject: Re: [PATCH v1 1/1] lib: make find_message{,by_filename) report errors
\r
41 Message-ID: <20111003174308.GD17905@mit.edu>
\r
42 References: <cover.1317660324.git.alip@exherbo.org>
\r
43 <1218582065f35bfcc5b84dfc1fbce21fc05034a6.1317660324.git.alip@exherbo.org>
\r
45 Content-Type: text/plain; charset=us-ascii
\r
46 Content-Disposition: inline
\r
48 <1218582065f35bfcc5b84dfc1fbce21fc05034a6.1317660324.git.alip@exherbo.org>
\r
49 User-Agent: Mutt/1.5.20 (2009-06-14)
\r
50 X-Brightmail-Tracker:
\r
51 H4sIAAAAAAAAA+NgFmpmleLIzCtJLcpLzFFi42IR4hRV1l3wudPP4MUSA4vrN2cyW/Tt+cbq
\r
52 wOSxc9Zddo9nq24xBzBFcdmkpOZklqUW6dslcGXMf3+GpeB7RcW3d9uYGxhnxHUxcnJICJhI
\r
53 zJ7wmwXCFpO4cG89WxcjF4eQwD5GiduXrkI56xkluhb8YYRwTjBJfG15yQLhLGGUWPlxPxtI
\r
54 P4uAisSWS1fAbDYBDYlt+5cDdXBwiAgoS/RtTwQJMwsYSRw+fQ5snbBAgMTJI3sYQWxeAR2J
\r
55 I/23WSFmNjBKvHz2jg0iIShxcuYTFohmLYkb/14ygcxkFpCWWP6PA8TkFAiXuNCvAFIhCnTB
\r
56 tf3tbBMYhWYhaZ6FpHkWQvMCRuZVjLIpuVW6uYmZOcWpybrFyYl5ealFuiZ6uZkleqkppZsY
\r
57 wWEtyb+D8dtBpUOMAhyMSjy8iuKdfkKsiWXFlbmHGCU5mJREeVd8AArxJeWnVGYkFmfEF5Xm
\r
58 pBYfYpTgYFYS4d1+GyjHm5JYWZValA+TkuZgURLnbdzh4CckkJ5YkpqdmlqQWgSTleHgUJLg
\r
59 nfgJqFGwKDU9tSItM6cEIc3EwQkynAdo+H6QGt7igsTc4sx0iPwpRkUpcd6pIAkBkERGaR5c
\r
60 LyztvGIUB3pFmHcvSBUPMGXBdb8CGswENDj1LtjgkkSElFQD4wK/J+zSpSeY7vuXLziW+OOW
\r
61 zPvtmmvjFVzzfh3juZzfr93W8WzXW+aGmolrk3UY+21tV/y7GbMu82m0WkXmi7rpjOdY9W3u
\r
62 bXiRzvR7j+/cmAbDiXenXZ7u+fbBiWV2AWHMj0+rTXPdfGR155OqH3euvd+/qNOi/+8ng6v3
\r
63 dxYFXvzP/vTHsiglluKMREMt5qLiRACkjqgzFgMAAA==
\r
64 Cc: Notmuch Mailing List <notmuch@notmuchmail.org>
\r
65 X-BeenThere: notmuch@notmuchmail.org
\r
66 X-Mailman-Version: 2.1.13
\r
68 List-Id: "Use and development of the notmuch mail system."
\r
69 <notmuch.notmuchmail.org>
\r
70 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
71 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
72 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
73 List-Post: <mailto:notmuch@notmuchmail.org>
\r
74 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
75 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
76 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
77 X-List-Received-Date: Mon, 03 Oct 2011 17:40:51 -0000
\r
79 All of the code looks good to me (and improving error handling is
\r
80 always a good thing). Some style nits are inline below.
\r
82 The changes to _resolve_message_id_to_thread_id and
\r
83 _notmuch_database_link_message_to_parents seem like just plain better
\r
84 error handling and unrelated to the find_message API changes. Perhaps
\r
85 these should be in a separate patch?
\r
87 Quoth Ali Polatel on Oct 03 at 7:49 pm:
\r
88 > Previously, the functions notmuch_database_find_message() and
\r
89 > notmuch_database_find_message_by_filename() functions did not properly
\r
90 > report error condition to the library user.
\r
92 > For more information, read the thread on the notmuch mailing list
\r
93 > starting with my mail "id:871uv2unfd.fsf@gmail.com"
\r
95 > Make these functions accept a pointer to 'notmuch_message_t' as argument
\r
96 > and return notmuch_status_t which may be used to check for any error
\r
99 > restore: Modify for the new notmuch_database_find_message()
\r
100 > new: Modify for the new notmuch_database_find_message_by_filename()
\r
102 > lib/database.cc | 90 ++++++++++++++++++++++++++++++++++------------------
\r
103 > lib/message.cc | 6 ++--
\r
104 > lib/notmuch.h | 61 +++++++++++++++++++++++++----------
\r
105 > notmuch-new.c | 4 ++-
\r
106 > notmuch-restore.c | 11 ++++--
\r
107 > 5 files changed, 115 insertions(+), 57 deletions(-)
\r
109 > diff --git a/lib/database.cc b/lib/database.cc
\r
110 > index 9299c8d..1705232 100644
\r
111 > --- a/lib/database.cc
\r
112 > +++ b/lib/database.cc
\r
113 > @@ -360,13 +360,17 @@ _message_id_compressed (void *ctx, const char *message_id)
\r
114 > return compressed;
\r
117 > -notmuch_message_t *
\r
118 > +notmuch_status_t
\r
119 > notmuch_database_find_message (notmuch_database_t *notmuch,
\r
120 > - const char *message_id)
\r
121 > + const char *message_id,
\r
122 > + notmuch_message_t **message)
\r
124 Perhaps this should be message_ret to clearly distinguish it as an
\r
128 > notmuch_private_status_t status;
\r
129 > unsigned int doc_id;
\r
131 > + if (message == NULL)
\r
132 > + return NOTMUCH_STATUS_NULL_POINTER;
\r
134 > if (strlen (message_id) > NOTMUCH_MESSAGE_ID_MAX)
\r
135 > message_id = _message_id_compressed (notmuch, message_id);
\r
137 > @@ -375,14 +379,21 @@ notmuch_database_find_message (notmuch_database_t *notmuch,
\r
138 > message_id, &doc_id);
\r
140 > if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)
\r
142 > + *message = NULL;
\r
144 > + *message = _notmuch_message_create (notmuch, notmuch, doc_id,
\r
146 > + if (*message == NULL)
\r
147 > + return NOTMUCH_STATUS_OUT_OF_MEMORY;
\r
150 > - return _notmuch_message_create (notmuch, notmuch, doc_id, NULL);
\r
151 > + return NOTMUCH_STATUS_SUCCESS;
\r
152 > } catch (const Xapian::Error &error) {
\r
153 > fprintf (stderr, "A Xapian exception occurred finding message: %s.\n",
\r
154 > error.get_msg().c_str());
\r
155 > notmuch->exception_reported = TRUE;
\r
157 > + *message = NULL;
\r
158 > + return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
\r
162 > @@ -1311,7 +1322,8 @@ _get_metadata_thread_id_key (void *ctx, const char *message_id)
\r
164 > /* Find the thread ID to which the message with 'message_id' belongs.
\r
166 > - * Always returns a newly talloced string belonging to 'ctx'.
\r
167 > + * Note: 'thread_id' must not be NULL!
\r
168 > + * On success '*thread_id' is set to a newly talloced string belonging to 'ctx'.
\r
170 > * Note: If there is no message in the database with the given
\r
171 > * 'message_id' then a new thread_id will be allocated for this
\r
172 > @@ -1319,25 +1331,29 @@ _get_metadata_thread_id_key (void *ctx, const char *message_id)
\r
173 > * thread ID can be looked up if the message is added to the database
\r
176 > -static const char *
\r
177 > +static notmuch_status_t
\r
178 > _resolve_message_id_to_thread_id (notmuch_database_t *notmuch,
\r
180 > - const char *message_id)
\r
181 > + const char *message_id,
\r
182 > + const char **thread_id)
\r
187 > + notmuch_status_t status;
\r
188 > notmuch_message_t *message;
\r
189 > string thread_id_string;
\r
190 > - const char *thread_id;
\r
191 > char *metadata_key;
\r
192 > Xapian::WritableDatabase *db;
\r
194 > - message = notmuch_database_find_message (notmuch, message_id);
\r
195 > + status = notmuch_database_find_message (notmuch, message_id, &message);
\r
201 > - thread_id = talloc_steal (ctx, notmuch_message_get_thread_id (message));
\r
202 > + *thread_id = talloc_steal (ctx, notmuch_message_get_thread_id (message));
\r
204 > notmuch_message_destroy (message);
\r
206 > - return thread_id;
\r
207 > + return NOTMUCH_STATUS_SUCCESS;
\r
210 > /* Message has not been seen yet.
\r
211 > @@ -1351,15 +1367,15 @@ _resolve_message_id_to_thread_id (notmuch_database_t *notmuch,
\r
212 > thread_id_string = notmuch->xapian_db->get_metadata (metadata_key);
\r
214 > if (thread_id_string.empty()) {
\r
215 > - thread_id = _notmuch_database_generate_thread_id (notmuch);
\r
216 > - db->set_metadata (metadata_key, thread_id);
\r
217 > + *thread_id = talloc_strdup (ctx, _notmuch_database_generate_thread_id (notmuch));
\r
218 > + db->set_metadata (metadata_key, *thread_id);
\r
220 > - thread_id = thread_id_string.c_str();
\r
221 > + *thread_id = talloc_strdup(ctx, thread_id_string.c_str());
\r
223 Missing space after talloc_strdup.
\r
227 > talloc_free (metadata_key);
\r
229 > - return talloc_strdup (ctx, thread_id);
\r
230 > + return NOTMUCH_STATUS_SUCCESS;
\r
233 > static notmuch_status_t
\r
234 > @@ -1446,9 +1462,12 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch,
\r
235 > _notmuch_message_add_term (message, "reference",
\r
236 > parent_message_id);
\r
238 > - parent_thread_id = _resolve_message_id_to_thread_id (notmuch,
\r
240 > - parent_message_id);
\r
241 > + ret = _resolve_message_id_to_thread_id (notmuch,
\r
243 > + parent_message_id,
\r
244 > + &parent_thread_id);
\r
248 > if (*thread_id == NULL) {
\r
249 > *thread_id = talloc_strdup (message, parent_thread_id);
\r
250 > @@ -1759,11 +1778,12 @@ notmuch_status_t
\r
251 > notmuch_database_remove_message (notmuch_database_t *notmuch,
\r
252 > const char *filename)
\r
254 > - notmuch_message_t *message =
\r
255 > - notmuch_database_find_message_by_filename (notmuch, filename);
\r
256 > - notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
\r
257 > + notmuch_status_t status;
\r
258 > + notmuch_message_t *message;
\r
261 > + status = notmuch_database_find_message_by_filename (notmuch, filename, &message);
\r
263 > + if (status == NOTMUCH_STATUS_SUCCESS && message) {
\r
264 > status = _notmuch_message_remove_filename (message, filename);
\r
265 > if (status == NOTMUCH_STATUS_SUCCESS)
\r
266 > _notmuch_message_delete (message);
\r
268 This isn't a problem with your patch, but shouldn't this function be
\r
269 notmuch_message_destroy'ing message?
\r
271 > @@ -1774,24 +1794,27 @@ notmuch_database_remove_message (notmuch_database_t *notmuch,
\r
275 > -notmuch_message_t *
\r
276 > +notmuch_status_t
\r
277 > notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
\r
278 > - const char *filename)
\r
279 > + const char *filename,
\r
280 > + notmuch_message_t **message)
\r
286 > const char *prefix = _find_prefix ("file-direntry");
\r
287 > char *direntry, *term;
\r
288 > Xapian::PostingIterator i, end;
\r
289 > - notmuch_message_t *message = NULL;
\r
290 > notmuch_status_t status;
\r
292 > + if (message == NULL)
\r
293 > + return NOTMUCH_STATUS_NULL_POINTER;
\r
295 > local = talloc_new (notmuch);
\r
298 > status = _notmuch_database_filename_to_direntry (local, notmuch,
\r
299 > filename, &direntry);
\r
304 > term = talloc_asprintf (local, "%s%s", prefix, direntry);
\r
306 > @@ -1800,19 +1823,24 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
\r
308 > notmuch_private_status_t private_status;
\r
310 > - message = _notmuch_message_create (notmuch, notmuch,
\r
311 > - *i, &private_status);
\r
312 > + *message = _notmuch_message_create (notmuch, notmuch,
\r
313 > + *i, &private_status);
\r
314 > + if (*message == NULL)
\r
315 > + status = NOTMUCH_STATUS_OUT_OF_MEMORY;
\r
317 > } catch (const Xapian::Error &error) {
\r
318 > fprintf (stderr, "Error: A Xapian exception occurred finding message by filename: %s\n",
\r
319 > error.get_msg().c_str());
\r
320 > notmuch->exception_reported = TRUE;
\r
321 > - message = NULL;
\r
322 > + status = NOTMUCH_STATUS_OUT_OF_MEMORY;
\r
326 > talloc_free (local);
\r
328 > - return message;
\r
330 > + *message = NULL;
\r
334 > notmuch_string_list_t *
\r
335 > diff --git a/lib/message.cc b/lib/message.cc
\r
336 > index 531d304..2a85744 100644
\r
337 > --- a/lib/message.cc
\r
338 > +++ b/lib/message.cc
\r
339 > @@ -216,11 +216,11 @@ _notmuch_message_create_for_message_id (notmuch_database_t *notmuch,
\r
340 > unsigned int doc_id;
\r
343 > - *status_ret = NOTMUCH_PRIVATE_STATUS_SUCCESS;
\r
345 > - message = notmuch_database_find_message (notmuch, message_id);
\r
346 > + *status_ret = (notmuch_private_status_t) notmuch_database_find_message (notmuch, message_id, &message);
\r
348 Long line, should probably be wrapped.
\r
351 > return talloc_steal (notmuch, message);
\r
352 > + else if (*status_ret)
\r
355 > term = talloc_asprintf (NULL, "%s%s",
\r
356 > _find_prefix ("id"), message_id);
\r
357 > diff --git a/lib/notmuch.h b/lib/notmuch.h
\r
358 > index 6d7a99f..08b4ce2 100644
\r
359 > --- a/lib/notmuch.h
\r
360 > +++ b/lib/notmuch.h
\r
361 > @@ -347,35 +347,60 @@ notmuch_database_remove_message (notmuch_database_t *database,
\r
363 > /* Find a message with the given message_id.
\r
365 > - * If the database contains a message with the given message_id, then
\r
366 > - * a new notmuch_message_t object is returned. The caller should call
\r
367 > - * notmuch_message_destroy when done with the message.
\r
368 > + * If message with the given message_id is found then, on successful return
\r
372 > + * (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to a message object.
\r
373 > + * The user should call notmuch_message_destroy when done with the message.
\r
375 Probably s/user/caller/, since "the user" is the person sitting at the
\r
376 keyboard. (notmuch.h isn't very good about this, but it does use
\r
377 "caller" more often than "user").
\r
379 > - * This function returns NULL in the following situations:
\r
380 > + * On any failure or when the message is not found, this function initializes
\r
381 > + * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the
\r
382 > + * user is supposed to check '*message' for NULL to find out whether the
\r
383 > + * message with the given message_id was found.
\r
385 > - * * No message is found with the given message_id
\r
386 > - * * An out-of-memory situation occurs
\r
387 > - * * A Xapian exception occurs
\r
388 > + * Note: The argument 'message' must not be NULL!
\r
390 Since it's clearly specified what happens if 'message' is NULL, this
\r
391 note isn't necessary.
\r
394 > + * Return value:
\r
396 > + * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'.
\r
398 > + * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL
\r
400 > + * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating message object
\r
402 > + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
\r
404 > -notmuch_message_t *
\r
405 > +notmuch_status_t
\r
406 > notmuch_database_find_message (notmuch_database_t *database,
\r
407 > - const char *message_id);
\r
408 > + const char *message_id,
\r
409 > + notmuch_message_t **message);
\r
411 > /* Find a message with the given filename.
\r
413 > - * If the database contains a message with the given filename, then a
\r
414 > - * new notmuch_message_t object is returned. The caller should call
\r
415 > - * notmuch_message_destroy when done with the message.
\r
416 > + * If the database contains a message with the given filename then, on
\r
417 > + * successful return (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to
\r
418 > + * a message object. The user should call notmuch_message_destroy when done
\r
419 > + * with the message.
\r
421 Same comment about "user" as above.
\r
424 > - * This function returns NULL in the following situations:
\r
425 > + * On any failure or when the message is not found, this function initializes
\r
426 > + * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the
\r
427 > + * user is supposed to check '*message' for NULL to find out whether the
\r
428 > + * message with the given filename is found.
\r
430 > - * * No message is found with the given filename
\r
431 > - * * An out-of-memory situation occurs
\r
432 > - * * A Xapian exception occurs
\r
433 > + * Note: The argument 'message' must not be NULL!
\r
435 Same comment about this note as above.
\r
438 > + * Return value:
\r
440 > + * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'
\r
442 > + * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL
\r
444 > + * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating the message object
\r
446 > + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred
\r
448 > -notmuch_message_t *
\r
449 > +notmuch_status_t
\r
450 > notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,
\r
451 > - const char *filename);
\r
452 > + const char *filename,
\r
453 > + notmuch_message_t **message);
\r
455 > /* Return a list of all tags found in the database.
\r
457 > diff --git a/notmuch-new.c b/notmuch-new.c
\r
458 > index e79593c..96a1e31 100644
\r
459 > --- a/notmuch-new.c
\r
460 > +++ b/notmuch-new.c
\r
461 > @@ -743,7 +743,9 @@ remove_filename (notmuch_database_t *notmuch,
\r
462 > status = notmuch_database_begin_atomic (notmuch);
\r
465 > - message = notmuch_database_find_message_by_filename (notmuch, path);
\r
466 > + status = notmuch_database_find_message_by_filename (notmuch, path, &message);
\r
467 > + if (status || message == NULL)
\r
469 > status = notmuch_database_remove_message (notmuch, path);
\r
470 > if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {
\r
471 > add_files_state->renamed_messages++;
\r
472 > diff --git a/notmuch-restore.c b/notmuch-restore.c
\r
473 > index f095f64..e4a5355 100644
\r
474 > --- a/notmuch-restore.c
\r
475 > +++ b/notmuch-restore.c
\r
476 > @@ -87,10 +87,13 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])
\r
477 > file_tags = xstrndup (line + match[2].rm_so,
\r
478 > match[2].rm_eo - match[2].rm_so);
\r
480 > - message = notmuch_database_find_message (notmuch, message_id);
\r
481 > - if (message == NULL) {
\r
482 > - fprintf (stderr, "Warning: Cannot apply tags to missing message: %s\n",
\r
484 > + status = notmuch_database_find_message (notmuch, message_id, &message);
\r
485 > + if (status || message == NULL) {
\r
486 > + fprintf (stderr, "Warning: Cannot apply tags to %smessage: %s\n",
\r
487 > + message ? "" : "missing ", message_id);
\r
489 > + fprintf (stderr, "%s\n",
\r
490 > + notmuch_status_to_string(status));
\r
496 Austin Clements MIT/'06/PhD/CSAIL
\r
497 amdragon@mit.edu http://web.mit.edu/amdragon
\r
498 Somewhere in the dream we call reality you will find me,
\r
499 searching for the reality we call dreams.
\r