1 /* The Ruby interface to the notmuch mail library
3 * Copyright © 2010 Ali Polatel
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see http://www.gnu.org/licenses/ .
18 * Author: Ali Polatel <alip@exherbo.org>
24 * call-seq: Notmuch::Database.new(path, [{:create => false, :mode => notmuch::MODE_READ_ONLY}]) => DB
26 * Create or open a notmuch database using the given path.
27 * If :create is +true+, create the database instead of opening.
28 * The argument :mode specifies the open mode of the database.
31 notmuch_rb_database_new(int argc, VALUE *argv, VALUE klass)
35 notmuch_database_t *db;
39 #if !defined(RSTRING_PTR)
40 #define RSTRING_PTR(v) (RSTRING((v))->ptr)
41 #endif /* !defined(RSTRING_PTR) */
44 rb_scan_args(argc, argv, "11", &pathv, &hashv);
46 SafeStringValue(pathv);
47 path = RSTRING_PTR(pathv);
50 Check_Type(hashv, T_HASH);
51 create = RTEST(rb_hash_aref(hashv, ID2SYM(ID_db_create)));
52 modev = rb_hash_aref(hashv, ID2SYM(ID_db_mode));
54 mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
55 else if (!FIXNUM_P(modev))
56 rb_raise(rb_eTypeError, ":mode isn't a Fixnum");
58 mode = FIX2INT(modev);
60 case NOTMUCH_DATABASE_MODE_READ_ONLY:
61 case NOTMUCH_DATABASE_MODE_READ_WRITE:
64 rb_raise(rb_eTypeError, "Invalid mode");
70 mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
73 db = create ? notmuch_database_create(path) : notmuch_database_open(path, mode);
75 rb_raise(notmuch_rb_eDatabaseError, "Failed to open database");
77 return Data_Wrap_Struct(klass, NULL, NULL, db);
81 * call-seq: DB.close => nil
83 * Close the notmuch database.
86 notmuch_rb_database_close(VALUE self)
88 notmuch_database_t *db;
90 Data_Get_Struct(self, notmuch_database_t, db);
91 notmuch_database_close(db);
97 * call-seq: DB.path => String
99 * Return the path of the database
102 notmuch_rb_database_path(VALUE self)
104 notmuch_database_t *db;
106 Data_Get_Struct(self, notmuch_database_t, db);
108 return rb_str_new2(notmuch_database_get_path(db));
112 * call-seq: DB.version => Fixnum
114 * Return the version of the database
117 notmuch_rb_database_version(VALUE self)
119 notmuch_database_t *db;
121 Data_Get_Struct(self, notmuch_database_t, db);
123 return INT2FIX(notmuch_database_get_version(db));
127 * call-seq: DB.needs_upgrade? => true or false
129 * Return the +true+ if the database needs upgrading, +false+ otherwise
132 notmuch_rb_database_needs_upgrade(VALUE self)
134 notmuch_database_t *db;
136 Data_Get_Struct(self, notmuch_database_t, db);
138 return notmuch_database_needs_upgrade(db) ? Qtrue : Qfalse;
142 notmuch_rb_upgrade_notify(void *closure, double progress)
144 VALUE *block = (VALUE *)closure;
145 rb_funcall(*block, ID_call, 1, rb_float_new(progress));
149 * call-seq: DB.upgrade! [{|progress| block }] => nil
151 * Upgrade the database.
153 * If a block is given the block is called with a progress indicator as a
154 * floating point value in the range of [0.0..1.0].
157 notmuch_rb_database_upgrade(VALUE self)
159 notmuch_status_t ret;
160 void (*pnotify) (void *closure, double progress);
161 notmuch_database_t *db;
164 Data_Get_Struct(self, notmuch_database_t, db);
166 if (rb_block_given_p()) {
167 pnotify = notmuch_rb_upgrade_notify;
168 block = rb_block_proc();
173 ret = notmuch_database_upgrade(db, pnotify, pnotify ? &block : NULL);
174 notmuch_rb_status_raise(ret);
180 * call-seq: DB.get_directory(path) => DIR
182 * Retrieve a directory object from the database for 'path'
185 notmuch_rb_database_get_directory(VALUE self, VALUE pathv)
188 notmuch_directory_t *dir;
189 notmuch_database_t *db;
191 Data_Get_Struct(self, notmuch_database_t, db);
193 #if !defined(RSTRING_PTR)
194 #define RSTRING_PTR(v) (RSTRING((v))->ptr)
195 #endif /* !defined(RSTRING_PTR) */
197 SafeStringValue(pathv);
198 path = RSTRING_PTR(pathv);
200 dir = notmuch_database_get_directory(db, path);
202 rb_raise(notmuch_rb_eXapianError, "Xapian exception");
204 return Data_Wrap_Struct(notmuch_rb_cDirectory, NULL, NULL, dir);
208 * call-seq: DB.add_message(path) => MESSAGE, isdup
210 * Add a message to the database and return it.
212 * +isdup+ is a boolean that specifies whether the added message was a
216 notmuch_rb_database_add_message(VALUE self, VALUE pathv)
219 notmuch_status_t ret;
220 notmuch_message_t *message;
221 notmuch_database_t *db;
223 Data_Get_Struct(self, notmuch_database_t, db);
225 #if !defined(RSTRING_PTR)
226 #define RSTRING_PTR(v) (RSTRING((v))->ptr)
227 #endif /* !defined(RSTRING_PTR) */
229 SafeStringValue(pathv);
230 path = RSTRING_PTR(pathv);
232 ret = notmuch_database_add_message(db, path, &message);
233 notmuch_rb_status_raise(ret);
234 return rb_assoc_new(Data_Wrap_Struct(notmuch_rb_cMessage, NULL, NULL, message),
235 (ret == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) ? Qtrue : Qfalse);
239 * call-seq: DB.remove_message(path) => isdup
241 * Remove a message from the database.
243 * +isdup+ is a boolean that specifies whether the removed message was a
247 notmuch_rb_database_remove_message(VALUE self, VALUE pathv)
250 notmuch_status_t ret;
251 notmuch_database_t *db;
253 Data_Get_Struct(self, notmuch_database_t, db);
255 #if !defined(RSTRING_PTR)
256 #define RSTRING_PTR(v) (RSTRING((v))->ptr)
257 #endif /* !defined(RSTRING_PTR) */
259 SafeStringValue(pathv);
260 path = RSTRING_PTR(pathv);
262 ret = notmuch_database_remove_message(db, path);
263 notmuch_rb_status_raise(ret);
264 return (ret == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) ? Qtrue : Qfalse;
268 * call-seq: DB.query(query) => QUERY
270 * Retrieve a query object for the query string 'query'
273 notmuch_rb_database_query_create(VALUE self, VALUE qstrv)
276 notmuch_query_t *query;
277 notmuch_database_t *db;
279 Data_Get_Struct(self, notmuch_database_t, db);
281 #if !defined(RSTRING_PTR)
282 #define RSTRING_PTR(v) (RSTRING((v))->ptr)
283 #endif /* !defined(RSTRING_PTR) */
285 SafeStringValue(qstrv);
286 qstr = RSTRING_PTR(qstrv);
288 query = notmuch_query_create(db, qstr);
290 rb_raise(notmuch_rb_eMemoryError, "out of memory");
292 return Data_Wrap_Struct(notmuch_rb_cQuery, NULL, NULL, query);