diff --git a/lib/Makefile.local b/lib/Makefile.local index 36c39243..76b57cb2 100644 --- a/lib/Makefile.local +++ b/lib/Makefile.local @@ -49,6 +49,7 @@ libnotmuch_cxx_srcs = \ $(dir)/index.cc \ $(dir)/message.cc \ $(dir)/query.cc \ + $(dir)/config.cc \ $(dir)/thread.cc libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o) diff --git a/lib/config.cc b/lib/config.cc new file mode 100644 index 00000000..9ca74bf5 --- /dev/null +++ b/lib/config.cc @@ -0,0 +1,87 @@ +/* config.cc - API for database metadata + * + * Copyright © 2016 David Bremner + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ . + * + * Author: David Bremner + */ + +#include "notmuch.h" +#include "notmuch-private.h" +#include "database-private.h" + +static const std::string CONFIG_PREFIX = "C"; + +notmuch_status_t +notmuch_database_set_config (notmuch_database_t *notmuch, + const char *key, + const char *value) +{ + notmuch_status_t status; + Xapian::WritableDatabase *db; + + status = _notmuch_database_ensure_writable (notmuch); + if (status) + return status; + + try { + db = static_cast (notmuch->xapian_db); + db->set_metadata (CONFIG_PREFIX + key, value); + } catch (const Xapian::Error &error) { + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; + notmuch->exception_reported = TRUE; + _notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n", + error.get_msg().c_str()); + } + return NOTMUCH_STATUS_SUCCESS; +} + +static notmuch_status_t +_metadata_value (notmuch_database_t *notmuch, + const char *key, + std::string &value) +{ + notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; + + try { + value = notmuch->xapian_db->get_metadata (CONFIG_PREFIX + key); + } catch (const Xapian::Error &error) { + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; + notmuch->exception_reported = TRUE; + _notmuch_database_log (notmuch, "Error: A Xapian exception occurred getting metadata: %s\n", + error.get_msg().c_str()); + } + return status; +} + +notmuch_status_t +notmuch_database_get_config (notmuch_database_t *notmuch, + const char *key, + char **value) +{ + std::string strval; + notmuch_status_t status; + + if (! value) + return NOTMUCH_STATUS_NULL_POINTER; + + status = _metadata_value (notmuch, key, strval); + if (status) + return status; + + *value = strdup (strval.c_str ()); + + return NOTMUCH_STATUS_SUCCESS; +} diff --git a/lib/notmuch.h b/lib/notmuch.h index 3a092efc..c827e02d 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -1838,6 +1838,26 @@ notmuch_filenames_move_to_next (notmuch_filenames_t *filenames); void notmuch_filenames_destroy (notmuch_filenames_t *filenames); + +/** + * set config 'key' to 'value' + * + */ +notmuch_status_t +notmuch_database_set_config (notmuch_database_t *db, const char *key, const char *value); + +/** + * retrieve config item 'key', assign to 'value' + * + * keys which have not been previously set with n_d_set_config will + * return an empty string. + * + * return value is allocated by malloc and should be freed by the + * caller. + */ +notmuch_status_t +notmuch_database_get_config (notmuch_database_t *db, const char *key, char **value); + /** * interrogate the library for compile time features */ diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh new file mode 100755 index 00000000..85e44979 --- /dev/null +++ b/test/T590-libconfig.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +test_description="library config API" + +. ./test-lib.sh || exit 1 + +add_email_corpus + +cat < c_head +#include +#include +#include +#include + +void run(int line, notmuch_status_t ret) +{ + if (ret) { + fprintf (stderr, "line %d: %s\n", line, ret); + exit (1); + } +} + +#define RUN(v) run(__LINE__, v); + +int main (int argc, char** argv) +{ + notmuch_database_t *db; + char *val; + notmuch_status_t stat; + + RUN(notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db)); + +EOF + +cat < c_tail + RUN(notmuch_database_destroy(db)); +} +EOF + +test_begin_subtest "notmuch_database_{set,get}_config" +cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} +{ + RUN(notmuch_database_set_config (db, "testkey1", "testvalue1")); + RUN(notmuch_database_set_config (db, "testkey2", "testvalue2")); + RUN(notmuch_database_get_config (db, "testkey1", &val)); + printf("testkey1 = %s\n", val); + RUN(notmuch_database_get_config (db, "testkey2", &val)); + printf("testkey2 = %s\n", val); +} +EOF +cat <<'EOF' >EXPECTED +== stdout == +testkey1 = testvalue1 +testkey2 = testvalue2 +== stderr == +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_done