MySQL 9.3.0
Source Code Documentation
config_section_printer.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2025, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQLROUTER_CONFIG_SECTION_PRINTER_INCLUDED
27#define MYSQLROUTER_CONFIG_SECTION_PRINTER_INCLUDED
28
29#include "harness_export.h"
30
31#include <algorithm>
32#include <map>
33#include <ostream>
34#include <set>
35#include <string>
36#include <utility>
37#include <vector>
38
39#include "config_builder.h"
40
41namespace mysql_harness {
42
43class HARNESS_EXPORT ConfigSectionPrinter {
44 public:
46 std::ostream &ostream,
47 const std::map<std::string, std::string> &config_cmdln_options,
48 const std::string &section_name)
49 : ostream_(ostream),
50 config_cmdln_options_(config_cmdln_options),
51 section_name_(section_name) {
52 auto section_name_lc = section_name;
53 std::transform(section_name_lc.begin(), section_name_lc.end(),
54 section_name_lc.begin(), ::tolower);
55
56 used_sections_.insert(section_name_lc);
57 }
58
59 ConfigSectionPrinter &add_line(std::string_view key, const std::string &value,
60 bool force_empty = false) {
61 std::string key_s(key);
62 std::string cmdln_option_key = section_name_ + "." + key_s;
63 std::transform(cmdln_option_key.begin(), cmdln_option_key.end(),
64 cmdln_option_key.begin(), ::tolower);
65
66 // cmdline options overwrite internal defaults.
67 if (config_cmdln_options_.contains(cmdln_option_key)) {
68 section_options_.emplace_back(key,
69 config_cmdln_options_.at(cmdln_option_key));
70
71 used_cmdln_options_.insert(key_s);
72 } else if (!value.empty() || force_empty) {
73 section_options_.emplace_back(key, value);
74 }
75
76 return *this;
77 }
78
80 // got through all the command line options for this section and see if
81 // there are some that user provided and we did not use them yet, now is
82 // time to add them to our section
83 for (const auto &cmdln_option : config_cmdln_options_) {
84 const auto &cmdln_option_key = cmdln_option.first;
85 const auto dot = cmdln_option_key.find('.');
86 if (dot == std::string::npos) continue;
87 const std::string section = cmdln_option_key.substr(0, dot);
88
89 std::string section_name_lowerc = section_name_;
90 std::transform(section_name_lowerc.begin(), section_name_lowerc.end(),
91 section_name_lowerc.begin(), ::tolower);
92
93 if (section != section_name_lowerc) continue;
94
95 const std::string option =
96 cmdln_option_key.substr(dot + 1, cmdln_option_key.length() - dot - 1);
97
98 if (!used_cmdln_options_.contains(option))
99 section_options_.emplace_back(option, cmdln_option.second);
100 }
101
102 ostream_ << ConfigBuilder::build_section(section_name_, section_options_);
103 }
104
106 std::ostream &ostream,
107 const std::map<std::string, std::string> &config_cmdln_options) {
108 std::string current_section;
109 std::vector<ConfigBuilder::kv_type> section_options;
110
111 for (const auto &cmdln_option : config_cmdln_options) {
112 const auto &cmdln_option_key = cmdln_option.first;
113 const auto dot = cmdln_option_key.find('.');
114 // that should be checked before
115 assert(dot != std::string::npos);
116 const std::string section_name = cmdln_option_key.substr(0, dot);
117
118 // MRS bootstrap is currently done as a separate step, if we add the
119 // configuration overwrites here it will fail later complaining that there
120 // already is a mysql_rest_service section
121 if (section_name == "mysql_rest_service") {
122 continue;
123 }
124
125 if (used_sections_.contains(section_name)) {
126 continue;
127 }
128
129 if (section_name != current_section) {
130 if (!current_section.empty()) {
131 ostream << ConfigBuilder::build_section(current_section,
132 section_options);
133 }
134 current_section = section_name;
135 section_options.clear();
136 }
137
138 const std::string option =
139 cmdln_option_key.substr(dot + 1, cmdln_option_key.length() - dot - 1);
140
141 section_options.emplace_back(option, cmdln_option.second);
142 }
143
144 if (!current_section.empty()) {
145 ostream << ConfigBuilder::build_section(current_section, section_options);
146 }
147 }
148
149 private:
150 std::ostream &ostream_;
151 const std::map<std::string, std::string> &config_cmdln_options_;
152 const std::string section_name_;
153
154 std::vector<ConfigBuilder::kv_type> section_options_;
155
156 std::set<std::string> used_cmdln_options_;
157 static std::set<std::string> used_sections_;
158};
159
160} // namespace mysql_harness
161
162#endif
static std::string build_section(const std::string &section, const std::initializer_list< kv_type > &pairs)
build a config file section from key-value pairs.
Definition: config_builder.h:50
Definition: config_section_printer.h:43
const std::map< std::string, std::string > & config_cmdln_options_
Definition: config_section_printer.h:151
static std::set< std::string > used_sections_
Definition: config_section_printer.h:157
static void add_remaining_sections(std::ostream &ostream, const std::map< std::string, std::string > &config_cmdln_options)
Definition: config_section_printer.h:105
ConfigSectionPrinter & add_line(std::string_view key, const std::string &value, bool force_empty=false)
Definition: config_section_printer.h:59
std::set< std::string > used_cmdln_options_
Definition: config_section_printer.h:156
std::vector< ConfigBuilder::kv_type > section_options_
Definition: config_section_printer.h:154
const std::string section_name_
Definition: config_section_printer.h:152
ConfigSectionPrinter(std::ostream &ostream, const std::map< std::string, std::string > &config_cmdln_options, const std::string &section_name)
Definition: config_section_printer.h:45
std::ostream & ostream_
Definition: config_section_printer.h:150
~ConfigSectionPrinter()
Definition: config_section_printer.h:79
ValueType value(const std::optional< ValueType > &v)
Definition: gtid.h:83
char tolower(const char &ch)
Definition: parsing_helpers.h:41
Definition: common.h:44
std::basic_string< Char > transform(std::basic_string_view< Char > s, F fun)
Definition: utils_string.h:53
required string key
Definition: replication_asynchronous_connection_failover.proto:60