const char *value)
{
notmuch_status_t status;
- Xapian::WritableDatabase *db;
status = _notmuch_database_ensure_writable (notmuch);
if (status)
return status;
+ if (! notmuch->config) {
+ if ((status = _notmuch_config_load_from_database (notmuch)))
+ return status;
+ }
+
try {
- db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
- db->set_metadata (CONFIG_PREFIX + key, value);
+ notmuch->writable_xapian_db->set_metadata (CONFIG_PREFIX + key, value);
} catch (const Xapian::Error &error) {
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
- notmuch->exception_reported = TRUE;
+ notmuch->exception_reported = true;
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
}
+
+ if (status)
+ return status;
+
+ _notmuch_string_map_set (notmuch->config, key, value);
+
return NOTMUCH_STATUS_SUCCESS;
}
value = notmuch->xapian_db->get_metadata (CONFIG_PREFIX + key);
} catch (const Xapian::Error &error) {
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
- notmuch->exception_reported = TRUE;
+ notmuch->exception_reported = true;
_notmuch_database_log (notmuch, "Error: A Xapian exception occurred getting metadata: %s\n",
- error.get_msg().c_str());
+ error.get_msg ().c_str ());
}
return status;
}
const char *key,
char **value)
{
- std::string strval;
+ const char* stored_val;
notmuch_status_t status;
+ if (! notmuch->config) {
+ if ((status = _notmuch_config_load_from_database (notmuch)))
+ return status;
+ }
+
if (! value)
return NOTMUCH_STATUS_NULL_POINTER;
- status = _metadata_value (notmuch, key, strval);
- if (status)
- return status;
-
- *value = strdup (strval.c_str ());
+ stored_val = _notmuch_string_map_get (notmuch->config, key);
+ if (! stored_val) {
+ /* XXX in principle this API should be fixed so empty string
+ * is distinguished from not found */
+ *value = strdup("");
+ } else {
+ *value = strdup (stored_val);
+ }
return NOTMUCH_STATUS_SUCCESS;
}
goto DONE;
}
- talloc_set_destructor (list, _notmuch_config_list_destroy);
list->notmuch = notmuch;
list->current_key = NULL;
list->current_val = NULL;
try {
new(&(list->iterator)) Xapian::TermIterator (notmuch->xapian_db->metadata_keys_begin
- (CONFIG_PREFIX + (prefix ? prefix : "")));
+ (CONFIG_PREFIX + (prefix ? prefix : "")));
+ talloc_set_destructor (list, _notmuch_config_list_destroy);
} catch (const Xapian::Error &error) {
_notmuch_database_log (notmuch, "A Xapian exception occurred getting metadata iterator: %s.\n",
- error.get_msg().c_str());
- notmuch->exception_reported = TRUE;
+ error.get_msg ().c_str ());
+ notmuch->exception_reported = true;
status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
*out = list;
DONE:
- if (status && list)
- talloc_free (list);
+ if (status) {
+ if (list) {
+ talloc_free (list);
+ if (status != NOTMUCH_STATUS_XAPIAN_EXCEPTION)
+ _notmuch_config_list_destroy (list);
+ }
+ } else {
+ talloc_set_destructor (list, _notmuch_config_list_destroy);
+ }
return status;
}
notmuch_config_list_valid (notmuch_config_list_t *metadata)
{
if (metadata->iterator == metadata->notmuch->xapian_db->metadata_keys_end ())
- return FALSE;
+ return false;
- return TRUE;
+ return true;
+}
+
+static inline char * _key_from_iterator (notmuch_config_list_t *list) {
+ return talloc_strdup (list, (*list->iterator).c_str () + CONFIG_PREFIX.length ());
}
const char *
if (list->current_key)
talloc_free (list->current_key);
- list->current_key = talloc_strdup (list, (*list->iterator).c_str () + CONFIG_PREFIX.length ());
+ list->current_key = _key_from_iterator (list);
return list->current_key;
}
{
std::string strval;
notmuch_status_t status;
- const char *key = notmuch_config_list_key (list);
+ char *key = _key_from_iterator (list);
/* TODO: better error reporting?? */
status = _metadata_value (list->notmuch, key, strval);
talloc_free (list->current_val);
list->current_val = talloc_strdup (list, strval.c_str ());
+ talloc_free (key);
return list->current_val;
}
{
talloc_free (list);
}
+
+notmuch_status_t
+_notmuch_config_load_from_database (notmuch_database_t *notmuch)
+{
+ notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+ notmuch_config_list_t *list;
+
+ if (notmuch->config == NULL)
+ notmuch->config = _notmuch_string_map_create (notmuch);
+
+ if (unlikely(notmuch->config == NULL))
+ return NOTMUCH_STATUS_OUT_OF_MEMORY;
+
+ status = notmuch_database_get_config_list (notmuch, "", &list);
+ if (status)
+ return status;
+
+ for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
+ _notmuch_string_map_append (notmuch->config,
+ notmuch_config_list_key (list),
+ notmuch_config_list_value (list));
+ }
+
+ return status;
+}
+
+notmuch_status_t
+_notmuch_config_load_from_file (notmuch_database_t *notmuch,
+ GKeyFile *file)
+{
+ notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+ gchar **groups,**keys, *val;
+
+ if (notmuch->config == NULL)
+ notmuch->config = _notmuch_string_map_create (notmuch);
+
+ if (unlikely(notmuch->config == NULL)) {
+ status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+ goto DONE;
+ }
+
+ for (groups = g_key_file_get_groups (file, NULL); *groups; groups++) {
+ for (keys = g_key_file_get_keys (file, *groups, NULL, NULL); *keys; keys++) {
+ char *absolute_key = talloc_asprintf(notmuch, "%s.%s", *groups, *keys);
+ val = g_key_file_get_value (file, *groups, *keys, NULL);
+ if (! val) {
+ status = NOTMUCH_STATUS_FILE_ERROR;
+ goto DONE;
+ }
+ _notmuch_string_map_set (notmuch->config, absolute_key, val);
+ talloc_free (absolute_key);
+ if (status)
+ goto DONE;
+ }
+ }
+
+ DONE:
+ return status;
+}