1 /* search_engines.h -- Prefiltering routines for SEARCH 2 * 3 * Copyright (c) 1994-2008 Carnegie Mellon University. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. The name "Carnegie Mellon University" must not be used to 18 * endorse or promote products derived from this software without 19 * prior written permission. For permission or any legal 20 * details, please contact 21 * Carnegie Mellon University 22 * Center for Technology Transfer and Enterprise Creation 23 * 4615 Forbes Avenue 24 * Suite 302 25 * Pittsburgh, PA 15213 26 * (412) 268-7393, fax: (412) 268-7395 27 * innovation@andrew.cmu.edu 28 * 29 * 4. Redistributions of any form whatsoever must retain the following 30 * acknowledgment: 31 * "This product includes software developed by Computing Services 32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 33 * 34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 41 */ 42 43 #ifndef INCLUDED_SEARCH_ENGINES_H 44 #define INCLUDED_SEARCH_ENGINES_H 45 46 #include "mailbox.h" 47 #include "message_guid.h" 48 #include "util.h" 49 #include "strarray.h" 50 51 #include "search_part.h" 52 53 typedef int (*search_hit_cb_t)(const char *mboxname, uint32_t uidvalidity, 54 uint32_t uid, void *rock); 55 typedef int (*search_snippet_cb_t)(struct mailbox *, uint32_t uid, 56 /* SEARCH_PART_* constants */int part, 57 const char *snippet, void *rock); 58 59 typedef struct search_builder search_builder_t; 60 struct search_builder { 61 /* These values are carefully chosen a) not to clash with the 62 * SEARCH_PART_* constants, and b) to reflect operator precedence */ 63 #define SEARCH_OP_AND 101 64 #define SEARCH_OP_OR 102 65 #define SEARCH_OP_NOT 103 66 void (*begin_boolean)(search_builder_t *, int op); 67 void (*end_boolean)(search_builder_t *, int op); 68 void (*match)(search_builder_t *, int part, const char *str); 69 void *(*get_internalised)(search_builder_t *); 70 int (*run)(search_builder_t *, search_hit_cb_t proc, void *rock); 71 }; 72 73 typedef struct search_snippet_markup { 74 const char *hi_start; 75 const char *hi_end; 76 const char *omit; 77 } search_snippet_markup_t; 78 79 extern search_snippet_markup_t default_snippet_markup; 80 81 /* The functions in search_text_receiver_t get called at least once for each part of every message. 82 The invocations form a sequence: 83 begin_message(message_t) 84 receiver->begin_part(<part1>) 85 receiver->append_text(<text>) (1 or more times) 86 receiver->end_part(<part1>) 87 ... 88 receiver->begin_part(<partN>) 89 receiver->append_text(<text>) (1 or more times) 90 receiver->end_part(<partN>) 91 receiver->end_message() 92 93 The parts need not arrive in any particular order, but each part 94 can only participate in one begin_part ... append_text ... end_part 95 sequence, and the sequences for different parts cannot be interleaved. 96 */ 97 typedef struct search_text_receiver search_text_receiver_t; 98 struct search_text_receiver { 99 int (*begin_mailbox)(search_text_receiver_t *, 100 struct mailbox *, int incremental); 101 uint32_t (*first_unindexed_uid)(search_text_receiver_t *); 102 int (*is_indexed)(search_text_receiver_t *, message_t *msg); 103 int (*begin_message)(search_text_receiver_t *, message_t *msg); 104 void (*begin_part)(search_text_receiver_t *, int part); 105 void (*append_text)(search_text_receiver_t *, const struct buf *); 106 void (*end_part)(search_text_receiver_t *, int part); 107 int (*end_message)(search_text_receiver_t *); 108 int (*end_mailbox)(search_text_receiver_t *, 109 struct mailbox *); 110 int (*flush)(search_text_receiver_t *); 111 }; 112 113 #define SEARCH_FLAG_CAN_BATCH (1<<0) 114 struct search_engine { 115 const char *name; 116 unsigned int flags; 117 #define _SEARCH_VERBOSE_MASK (0x7) 118 #define SEARCH_VERBOSE(v) ((v)&_SEARCH_VERBOSE_MASK) 119 #define SEARCH_MULTIPLE (1<<3) /* return results from 120 * multiple folders */ 121 #define SEARCH_UNINDEXED (1<<4) /* return unindexed messages 122 * as hits (doesn't work 123 * with MULTIPLE) */ 124 #define SEARCH_COMPACT_COPYONE (1<<5) /* if only one source, just copy */ 125 #define SEARCH_COMPACT_FILTER (1<<6) /* filter resulting DB for 126 * expunged records */ 127 #define SEARCH_COMPACT_REINDEX (1<<7) /* re-index all matching messages */ 128 search_builder_t *(*begin_search)(struct mailbox *, int opts); 129 void (*end_search)(search_builder_t *); 130 search_text_receiver_t *(*begin_update)(int verbose); 131 int (*end_update)(search_text_receiver_t *); 132 search_text_receiver_t *(*begin_snippets)(void *internalised, 133 int verbose, 134 search_snippet_markup_t *markup, 135 search_snippet_cb_t, 136 void *rock); 137 int (*end_snippets)(search_text_receiver_t *); 138 char *(*describe_internalised)(void *); 139 void (*free_internalised)(void *); 140 int (*start_daemon)(int verbose); 141 int (*stop_daemon)(int verbose); 142 int (*list_files)(const char *userid, strarray_t *); 143 int (*compact)(const char *userid, const char *tempdir, 144 const strarray_t *srctiers, const char *desttier, 145 int flags); 146 int (*deluser)(const char *userid); 147 }; 148 149 /* 150 * Search for messages which could match the query built with the 151 * search_builder_t. Calls 'proc' once for each hit found. If 'single' 152 * is true, only hits in 'mailbox' are reported; otherwise hits in any 153 * folder in the same conversation scope (i.e. the same user) as 154 * reported. 155 */ 156 extern search_builder_t *search_begin_search(struct mailbox *, int opts); 157 extern void search_end_search(search_builder_t *); 158 159 #define SEARCH_UPDATE_INCREMENTAL (1<<0) 160 #define SEARCH_UPDATE_NONBLOCKING (1<<1) 161 #define SEARCH_UPDATE_BATCH (1<<2) 162 search_text_receiver_t *search_begin_update(int verbose); 163 int search_update_mailbox(search_text_receiver_t *rx, 164 struct mailbox *mailbox, 165 int flags); 166 int search_end_update(search_text_receiver_t *rx); 167 search_text_receiver_t *search_begin_snippets(void *internalised, 168 int verbose, 169 search_snippet_markup_t *markup, 170 search_snippet_cb_t proc, 171 void *rock); 172 int search_end_snippets(search_text_receiver_t *rx); 173 /* Returns a new string which describes the internalised query, and must 174 * be free()d by the caller. Only useful for whitebox testing. */ 175 char *search_describe_internalised(void *internalised); 176 void search_free_internalised(void *internalised); 177 int search_start_daemon(int verbose); 178 int search_stop_daemon(int verbose); 179 int search_list_files(const char *userid, strarray_t *); 180 int search_compact(const char *userid, const char *tempdir, 181 const strarray_t *srctiers, const char *desttier, int verbose); 182 int search_deluser(const char *userid); 183 184 185 /* for debugging */ 186 extern const char *search_op_as_string(int op); 187 188 #endif 189