MySQL 8.4.0
Source Code Documentation
properties_impl.h
Go to the documentation of this file.
1/* Copyright (c) 2014, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef DD__PROPERTIES_IMPL_INCLUDED
25#define DD__PROPERTIES_IMPL_INCLUDED
26
27#include <assert.h>
28#include <map>
29#include <memory>
30#include <set>
31#include <string>
32#include <utility>
33
34#include "lex_string.h"
35
36#include "my_inttypes.h"
37#include "sql/dd/properties.h" // dd::Properties
38#include "sql/dd/string_type.h" // dd::String_type
39
40namespace dd {
41
42///////////////////////////////////////////////////////////////////////////
43
44/**
45 The Properties_impl class implements the Properties interface.
46
47 The key=value pairs are stored in a std::map. An instance can be created
48 either by means of the default constructor, which creates an object
49 with an empty map, or alternatively, it can be created by means of the
50 static parse_properties function with a String_type argument. The string
51 is supposed to contain a semicolon separated list of key=value pairs,
52 where the characters '=' and ';' also may be part of key or value by
53 escaping using the '\' as an escape character. The escape character
54 itself must also be escaped if being part of key or value. All characters
55 between '=' and ';' are considered part of key or value, whitespace is
56 not ignored.
57
58 Escaping is removed during parsing so the strings in the map are not
59 escaped. Escaping is only relevant in the context of raw strings that
60 are to be parsed, and raw strings that are returned containing all
61 key=value pairs.
62
63 Example (note \\ due to escaping of C string literals):
64 parse_properties("a=b;b = c") -> ("a", "b"), ("b ", " c")
65 parse_properties("a\\==b;b=\\;c") -> ("a=", "b"), ("b", ";c")
66
67 get("a=") == "b"
68 get("b") == ";c"
69
70 Additional key=value pairs may be added by means of the set function,
71 which takes a string argument that is assumed to be unescaped.
72
73 Please also refer to the comments in the file properties.h where the
74 interface is defined; the functions in the interface are commented there.
75*/
76
78 private:
79 /* Map containing the actual key-value pairs. */
81
82 /* Set containing the valid keys. An empty set means any key is valid. */
83 std::set<String_type> m_keys;
84
85 public:
86 Properties_impl() = default;
87
88 /* Constructor accepting a set of valid keys. */
89 Properties_impl(const std::set<String_type> &keys) : m_keys(keys) {}
90
91 virtual const Properties_impl *impl() const { return this; }
92
93 iterator begin() override { return m_map.begin(); }
94
95 const_iterator begin() const override { return m_map.begin(); }
96
97 iterator end() override { return m_map.end(); }
98
99 const_iterator end() const override { return m_map.end(); }
100
101 size_type size() const override { return m_map.size(); }
102
103 bool empty() const override { return m_map.empty(); }
104
105 void clear() override { return m_map.clear(); }
106
107 bool valid_key(const String_type &key) const override {
108 return (m_keys.empty() || m_keys.find(key) != m_keys.end());
109 }
110
111 bool exists(const String_type &key) const override {
112 return m_map.find(key) != m_map.end();
113 }
114
115 bool remove(const String_type &key) override {
116 iterator it = m_map.find(key);
117
118 if (it == m_map.end()) return true;
119
120 m_map.erase(it);
121 return false;
122 }
123
124 /**
125 Iterate over all entries in the private hash table. For each
126 key value pair, escape both key and value, and append the strings
127 to the result. Use '=' to separate key and value, and use ';'
128 to separate pairs.
129
130 Invalid keys are not included in the output. However, there should
131 never be a situation where invalid keys are present, so we just assert
132 that the keys are valid.
133
134 @return string containing all escaped key value pairs
135 */
136 const String_type raw_string() const override;
137
138 /**
139 Get the string value for a given key.
140
141 Return true if the operation fails, i.e., if the key does not exist
142 or if the key is invalid. Assert that the key exists in debug builds.
143
144 @param key key to lookup the value for
145 @param[out] value string value
146 @return Operation outcome, false if success, otherwise true
147 */
148 bool get(const String_type &key, String_type *value) const override;
149
150 /**
151 Set the key/value. If the key is invalid, a warning is written
152 to the error log. Assert that the key exists in debug builds.
153
154 @param key Key to set.
155 @param value Value to set.
156 @return Operation outcome, false if success, otherwise true
157 */
158 bool set(const String_type &key, const String_type &value) override;
159
160 /**
161 Insert key/value pairs from a different property object.
162
163 The set of valid keys is not copied, instead, the existing
164 set in the destination object is used to ignore all invalid
165 keys.
166
167 @param properties Source object.
168
169 @retval Operation outcome, false if no error, otherwise true.
170 */
171 bool insert_values(const Properties &properties) override;
172
173 /**
174 Insert key/value pairs from a string.
175
176 Parse the string and add key/value pairs to this object.
177 The existing set of valid keys in the destination object
178 is used to ignore all invalid keys.
179
180 @param raw_string String to be parsed.
181
182 @retval Operation outcome, false if no error, otherwise true.
183 */
184 bool insert_values(const String_type &raw_string) override;
185
186#ifdef EXTRA_CODE_FOR_UNIT_TESTING
187 /**
188 Extend the set of valid keys after the property object is
189 created. This can be used e.g. for the SE private data.
190
191 @pre There must be a set of valid keys already, or the
192 map of key-value pairs must be empty. Otherwise,
193 we risk making existing keys invalid, thus hiding
194 their values.
195
196 @param keys Set of additional keys to insert into
197 the set of valid keys.
198 */
199 void add_valid_keys(const std::set<String_type> &keys) {
200 assert(!m_keys.empty() || m_map.empty());
201 m_keys.insert(keys.begin(), keys.end());
202 }
203
204 /**
205 Remove the set of valid keys after the property object is
206 created. Convenience method used by unit tests.
207 */
208 void clear_valid_keys() { m_keys.clear(); }
209
210 /**
211 Get valid key at a certain index.
212
213 If the key set is empty, return a string representation of
214 the index is returned. If the index is out of bounds, return
215 the last key.
216
217 @note This is needed by unit tests to fill in
218 random key/value pairs without breaking the
219 check for valid keys.
220
221 @param index Index at which to get the valid key.
222
223 @retval Key at the given index, a string containing the index,
224 or the last key.
225 */
226 const String_type valid_key_at(size_t index) const {
227 if (m_keys.empty()) {
228 Stringstream_type ostream;
229 ostream << index;
230 return ostream.str();
231 }
232 if (m_keys.size() <= index) {
233 return *std::next(m_keys.begin(), m_keys.size() - 1);
234 }
235 return *std::next(m_keys.begin(), index);
236 }
237#endif
238};
239
240///////////////////////////////////////////////////////////////////////////
241
242} // namespace dd
243
244#endif // DD__PROPERTIES_IMPL_INCLUDED
The Properties_impl class implements the Properties interface.
Definition: properties_impl.h:77
bool empty() const override
Are there any key=value pairs?
Definition: properties_impl.h:103
virtual const Properties_impl * impl() const
Definition: properties_impl.h:91
const_iterator begin() const override
Definition: properties_impl.h:95
std::set< String_type > m_keys
Definition: properties_impl.h:83
bool insert_values(const Properties &properties) override
Insert key/value pairs from a different property object.
Definition: properties_impl.cc:104
iterator end() override
Definition: properties_impl.h:97
bool remove(const String_type &key) override
Remove the key=value pair for the given key if it exists.
Definition: properties_impl.h:115
void clear() override
Remove all key=value pairs.
Definition: properties_impl.h:105
const String_type raw_string() const override
Iterate over all entries in the private hash table.
Definition: properties_impl.cc:60
bool set(const String_type &key, const String_type &value) override
Set the key/value.
Definition: properties_impl.cc:94
const_iterator end() const override
Definition: properties_impl.h:99
Properties::Map m_map
Definition: properties_impl.h:80
bool exists(const String_type &key) const override
Check for the existence of a key=value pair given the key.
Definition: properties_impl.h:111
bool valid_key(const String_type &key) const override
Check if the submitted key is valid.
Definition: properties_impl.h:107
iterator begin() override
Definition: properties_impl.h:93
size_type size() const override
Get the number of key=value pairs.
Definition: properties_impl.h:101
bool get(const String_type &key, String_type *value) const override
Get the string value for a given key.
Definition: properties_impl.cc:77
Properties_impl(const std::set< String_type > &keys)
Definition: properties_impl.h:89
Properties_impl()=default
The Properties class defines an interface for storing key=value pairs, where both key and value may b...
Definition: properties.h:74
std::map< String_type, String_type > Map
Definition: properties.h:128
Map::iterator iterator
Definition: properties.h:130
std::map< String_type, String_type >::size_type size_type
Definition: properties.h:129
Map::const_iterator const_iterator
Definition: properties.h:131
static uint keys
Definition: hp_test2.cc:49
Some integer typedefs for easier portability.
The version of the current data dictionary table definitions.
Definition: dictionary_client.h:43
Char_stringstream_template< String_type_allocator > Stringstream_type
Instantiation of std::basic_stringstream with the same allocator as String_type.
Definition: string_type.h:72
Char_string_template< String_type_allocator > String_type
Definition: string_type.h:51
required string key
Definition: replication_asynchronous_connection_failover.proto:60