]> git.notmuchmail.org Git - notmuch/blob - bindings/python-cffi/notmuch2/_config.py
python/notmuch2: add bindings for the database config strings
[notmuch] / bindings / python-cffi / notmuch2 / _config.py
1 import collections.abc
2
3 import notmuch2._base as base
4 import notmuch2._capi as capi
5 import notmuch2._errors as errors
6
7 __all__ = ['ConfigMapping']
8
9 class ConfigIter(base.NotmuchIter):
10     def __init__(self, parent, iter_p):
11         super().__init__(
12             parent, iter_p,
13             fn_destroy=capi.lib.notmuch_config_list_destroy,
14             fn_valid=capi.lib.notmuch_config_list_valid,
15             fn_get=capi.lib.notmuch_config_list_key,
16             fn_next=capi.lib.notmuch_config_list_move_to_next)
17
18     def __next__(self):
19         item = super().__next__()
20         return base.BinString.from_cffi(item)
21
22 class ConfigMapping(base.NotmuchObject, collections.abc.MutableMapping):
23     """The config key/value pairs stored in the database.
24
25     The entries are exposed as a :class:`collections.abc.MutableMapping` object.
26     Note that setting a value to an empty string is the same as deleting it.
27
28     :param parent: the parent object
29     :param ptr_name: the name of the attribute on the parent which will
30        return the memory pointer.  This allows this object to
31        access the pointer via the parent's descriptor and thus
32        trigger :class:`MemoryPointer`'s memory safety.
33     """
34
35     def __init__(self, parent, ptr_name):
36         self._parent = parent
37         self._ptr = lambda: getattr(parent, ptr_name)
38
39     @property
40     def alive(self):
41         return self._parent.alive
42
43     def _destroy(self):
44         pass
45
46     def __getitem__(self, key):
47         if isinstance(key, str):
48             key = key.encode('utf-8')
49         val_pp = capi.ffi.new('char**')
50         ret = capi.lib.notmuch_database_get_config(self._ptr(), key, val_pp)
51         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
52             raise errors.NotmuchError(ret)
53         if val_pp[0] == "":
54             capi.lib.free(val_pp[0])
55             raise KeyError
56         val = base.BinString.from_cffi(val_pp[0])
57         capi.lib.free(val_pp[0])
58         return val
59
60     def __setitem__(self, key, val):
61         if isinstance(key, str):
62             key = key.encode('utf-8')
63         if isinstance(val, str):
64             val = val.encode('utf-8')
65         ret = capi.lib.notmuch_database_set_config(self._ptr(), key, val)
66         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
67             raise errors.NotmuchError(ret)
68
69     def __delitem__(self, key):
70         self[key] = ""
71
72     def __iter__(self):
73         """Return an iterator over the config items.
74
75         :raises NullPointerError: If the iterator can not be created.
76         """
77         configlist_pp = capi.ffi.new('notmuch_config_list_t**')
78         ret = capi.lib.notmuch_database_get_config_list(self._ptr(), b'', configlist_pp)
79         if ret != capi.lib.NOTMUCH_STATUS_SUCCESS:
80             raise errors.NotmuchError(ret)
81         return ConfigIter(self._parent, configlist_pp[0])
82
83     def __len__(self):
84         return sum(1 for t in self)