]> git.cworth.org Git - notmuch/blob - lib/message-property.cc
lib: bump LIBRARY_MINOR_VERSION
[notmuch] / lib / message-property.cc
1 /* message-property.cc - Properties are like tags, but (key,value) pairs.
2  * keys are allowed to repeat.
3  *
4  * This file is part of notmuch.
5  *
6  * Copyright © 2016 David Bremner
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see http://www.gnu.org/licenses/ .
20  *
21  * Author: David Bremner <david@tethera.net>
22  */
23
24 #include "notmuch-private.h"
25 #include "database-private.h"
26 #include "message-private.h"
27
28 notmuch_status_t
29 notmuch_message_get_property (notmuch_message_t *message, const char *key, const char **value)
30 {
31     if (! value)
32         return NOTMUCH_STATUS_NULL_POINTER;
33
34     *value = _notmuch_string_map_get (_notmuch_message_property_map (message), key);
35
36     return NOTMUCH_STATUS_SUCCESS;
37 }
38
39 static notmuch_status_t
40 _notmuch_message_modify_property (notmuch_message_t *message, const char *key, const char *value,
41                                   bool delete_it)
42 {
43     notmuch_private_status_t private_status;
44     notmuch_status_t status;
45     char *term = NULL;
46
47     status = _notmuch_database_ensure_writable (_notmuch_message_database (message));
48     if (status)
49         return status;
50
51     if (key == NULL || value == NULL)
52         return NOTMUCH_STATUS_NULL_POINTER;
53
54     if (strchr (key, '='))
55         return NOTMUCH_STATUS_ILLEGAL_ARGUMENT;
56
57     term = talloc_asprintf (message, "%s=%s", key, value);
58
59     if (delete_it)
60         private_status = _notmuch_message_remove_term (message, "property", term);
61     else
62         private_status = _notmuch_message_add_term (message, "property", term);
63
64     if (private_status)
65         return COERCE_STATUS (private_status,
66                               "Unhandled error modifying message property");
67     if (! _notmuch_message_frozen (message))
68         _notmuch_message_sync (message);
69
70     if (term)
71         talloc_free (term);
72
73     return NOTMUCH_STATUS_SUCCESS;
74 }
75
76 notmuch_status_t
77 notmuch_message_add_property (notmuch_message_t *message, const char *key, const char *value)
78 {
79     return _notmuch_message_modify_property (message, key, value, false);
80 }
81
82 notmuch_status_t
83 notmuch_message_remove_property (notmuch_message_t *message, const char *key, const char *value)
84 {
85     return _notmuch_message_modify_property (message, key, value, true);
86 }
87
88 static
89 notmuch_status_t
90 _notmuch_message_remove_all_properties (notmuch_message_t *message, const char *key, bool prefix)
91 {
92     notmuch_status_t status;
93     const char * term_prefix;
94
95     status = _notmuch_database_ensure_writable (_notmuch_message_database (message));
96     if (status)
97         return status;
98
99     _notmuch_message_invalidate_metadata (message, "property");
100     if (key)
101         term_prefix = talloc_asprintf (message, "%s%s%s", _find_prefix ("property"), key,
102                                        prefix ? "" : "=");
103     else
104         term_prefix = _find_prefix ("property");
105
106     /* XXX better error reporting ? */
107     _notmuch_message_remove_terms (message, term_prefix);
108
109     return NOTMUCH_STATUS_SUCCESS;
110 }
111
112 notmuch_status_t
113 notmuch_message_remove_all_properties (notmuch_message_t *message, const char *key)
114 {
115     return _notmuch_message_remove_all_properties (message, key, false);
116 }
117
118 notmuch_status_t
119 notmuch_message_remove_all_properties_with_prefix (notmuch_message_t *message, const char *prefix)
120 {
121     return _notmuch_message_remove_all_properties (message, prefix, true);
122 }
123
124 notmuch_message_properties_t *
125 notmuch_message_get_properties (notmuch_message_t *message, const char *key, notmuch_bool_t exact)
126 {
127     notmuch_string_map_t *map;
128     map = _notmuch_message_property_map (message);
129     return _notmuch_string_map_iterator_create (map, key, exact);
130 }
131
132 notmuch_bool_t
133 notmuch_message_properties_valid (notmuch_message_properties_t *properties)
134 {
135     return _notmuch_string_map_iterator_valid (properties);
136 }
137
138 void
139 notmuch_message_properties_move_to_next (notmuch_message_properties_t *properties)
140 {
141     return _notmuch_string_map_iterator_move_to_next (properties);
142 }
143
144 const char *
145 notmuch_message_properties_key (notmuch_message_properties_t *properties)
146 {
147     return _notmuch_string_map_iterator_key (properties);
148 }
149
150 const char *
151 notmuch_message_properties_value (notmuch_message_properties_t *properties)
152 {
153     return _notmuch_string_map_iterator_value (properties);
154 }
155
156 void
157 notmuch_message_properties_destroy (notmuch_message_properties_t *properties)
158 {
159     _notmuch_string_map_iterator_destroy (properties);
160 }