]> git.cworth.org Git - notmuch/blobdiff - bindings/ruby/defs.h
ruby: split database close and destroy
[notmuch] / bindings / ruby / defs.h
index 8fb47b4cd0fe19d141aef787a62093ba1e9a9bed..a33ef0da69d392467e64d747dae447f2adddf212 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <notmuch.h>
 #include <ruby.h>
+#include <talloc.h>
 
 extern VALUE notmuch_rb_cDatabase;
 extern VALUE notmuch_rb_cDirectory;
@@ -55,39 +56,101 @@ extern ID ID_db_mode;
 # define RSTRING_PTR(v) (RSTRING((v))->ptr)
 #endif /* !defined (RSTRING_PTR) */
 
-#define Data_Get_Notmuch_Object(obj, message, ptr)             \
+extern const rb_data_type_t notmuch_rb_object_type;
+extern const rb_data_type_t notmuch_rb_database_type;
+extern const rb_data_type_t notmuch_rb_directory_type;
+extern const rb_data_type_t notmuch_rb_filenames_type;
+extern const rb_data_type_t notmuch_rb_query_type;
+extern const rb_data_type_t notmuch_rb_threads_type;
+extern const rb_data_type_t notmuch_rb_thread_type;
+extern const rb_data_type_t notmuch_rb_messages_type;
+extern const rb_data_type_t notmuch_rb_message_type;
+extern const rb_data_type_t notmuch_rb_tags_type;
+
+#define Data_Get_Notmuch_Rb_Object(obj, type, ptr)                                 \
+    do {                                                                           \
+       (ptr) = rb_check_typeddata ((obj), (type));                                 \
+       if (RB_UNLIKELY (!(ptr))) {                                                 \
+           VALUE cname = rb_class_name (CLASS_OF ((obj)));                         \
+           rb_raise (rb_eRuntimeError, "%"PRIsVALUE" object destroyed", cname);    \
+       }                                                                           \
+    } while (0)
+
+#define Data_Get_Notmuch_Object(obj, type, ptr)                        \
     do {                                                       \
-       (ptr) = rb_data_object_get ((obj));                     \
-       if (!(ptr))                                             \
-       rb_raise (rb_eRuntimeError, (message));                 \
+       notmuch_rb_object_t *rb_wrapper;                        \
+       Data_Get_Notmuch_Rb_Object ((obj), (type), rb_wrapper); \
+       (ptr) = rb_wrapper->nm_object;                          \
     } while (0)
 
+#define Data_Wrap_Notmuch_Object(klass, type, ptr) \
+    TypedData_Wrap_Struct ((klass), (type), notmuch_rb_object_create ((ptr), "notmuch_rb_object: " __location__))
+
 #define Data_Get_Notmuch_Database(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "database closed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_database_type, (ptr))
 
 #define Data_Get_Notmuch_Directory(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "directory destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_directory_type, (ptr))
 
 #define Data_Get_Notmuch_FileNames(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "filenames destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_filenames_type, (ptr))
 
 #define Data_Get_Notmuch_Query(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "query destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_query_type, (ptr))
 
 #define Data_Get_Notmuch_Threads(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "threads destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_threads_type, (ptr))
 
 #define Data_Get_Notmuch_Messages(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "messages destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_messages_type, (ptr))
 
 #define Data_Get_Notmuch_Thread(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "thread destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_thread_type, (ptr))
 
 #define Data_Get_Notmuch_Message(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "message destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_message_type, (ptr))
 
 #define Data_Get_Notmuch_Tags(obj, ptr) \
-    Data_Get_Notmuch_Object ((obj), "tags destroyed", (ptr))
+    Data_Get_Notmuch_Object ((obj), &notmuch_rb_tags_type, (ptr))
+
+typedef struct {
+    void *nm_object;
+} notmuch_rb_object_t;
+
+static inline void *
+notmuch_rb_object_create (void *nm_object, const char *name)
+{
+    notmuch_rb_object_t *rb_wrapper = talloc_named_const (NULL, sizeof (*rb_wrapper), name);
+
+    if (RB_UNLIKELY (!rb_wrapper))
+       return NULL;
+
+    rb_wrapper->nm_object = nm_object;
+    talloc_steal (rb_wrapper, nm_object);
+    return rb_wrapper;
+}
+
+static inline void
+notmuch_rb_object_free (void *rb_wrapper)
+{
+    talloc_free (rb_wrapper);
+}
+
+static inline notmuch_status_t
+notmuch_rb_object_destroy (VALUE rb_object, const rb_data_type_t *type)
+{
+    notmuch_rb_object_t *rb_wrapper;
+    notmuch_status_t ret;
+
+    Data_Get_Notmuch_Rb_Object (rb_object, type, rb_wrapper);
+
+    /* Call the corresponding notmuch_*_destroy function */
+    ret = ((notmuch_status_t (*)(void *)) type->data) (rb_wrapper->nm_object);
+    notmuch_rb_object_free (rb_wrapper);
+    DATA_PTR (rb_object) = NULL;
+
+    return ret;
+}
 
 /* status.c */
 void
@@ -97,6 +160,9 @@ notmuch_rb_status_raise (notmuch_status_t status);
 VALUE
 notmuch_rb_database_alloc (VALUE klass);
 
+VALUE
+notmuch_rb_database_destroy (VALUE self);
+
 VALUE
 notmuch_rb_database_initialize (int argc, VALUE *argv, VALUE klass);
 
@@ -143,7 +209,7 @@ VALUE
 notmuch_rb_database_get_all_tags (VALUE self);
 
 VALUE
-notmuch_rb_database_query_create (VALUE self, VALUE qstrv);
+notmuch_rb_database_query_create (int argc, VALUE *argv, VALUE self);
 
 /* directory.c */
 VALUE