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