MySQL 8.0.30
Source Code Documentation
manifest.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2022, 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 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 MANIFEST_INCLUDED
24#define MANIFEST_INCLUDED
25
26#include <fstream> /* std::ifstream */
27#include <memory>
28#include <string>
29
30#include "scope_guard.h"
31
32#include "my_rapidjson_size_t.h"
33#include "rapidjson/document.h"
34#include "rapidjson/schema.h"
35
36namespace manifest {
37
39 "{"
40 " \"title\": \"Manifest validator version 1.0\","
41 " \"description\": \"Expected schema for version 1.0\","
42 " \"type\": \"object\","
43 " \"properties\": {"
44 " \"read_local_manifest\": {"
45 " \"description\": \"Flag to indicate that manifest information is in "
46 "data directory\","
47 " \"type\": \"boolean\""
48 " },"
49 " \"components\": {"
50 " \"description\": \"The list of components to be loaded at "
51 "bootstrap\","
52 " \"type\": \"string\""
53 " }"
54 " }"
55 "}";
56
57class Manifest_reader final {
58 public:
59 /*
60 Constructor
61
62 Reads manifest file if present.
63 Expected format: JSON.
64
65 @param [in] executable_path Executable location
66 @param [in] instance_path Location of specific instance
67 Must have separator character at the end
68 */
69
70 explicit Manifest_reader(const std::string executable_path,
71 const std::string instance_path,
72 std::string json_schema = manifest_version_1_0)
74 schema_(),
75 data_(),
76 file_present_(false),
77 valid_(false),
78 empty_(true),
79 ro_(true) {
80 std::string exe_path(executable_path);
81 std::size_t last_separator = exe_path.find_last_of("/\\");
82 std::string executable = exe_path.substr(last_separator + 1);
83 std::string path = exe_path.erase(last_separator + 1);
84#ifdef _WIN32
85 std::size_t ext = executable.find(".exe");
86 executable = executable.substr(0, ext);
87#endif // _WIN32
88 executable.append(".my");
89 if (instance_path.length() == 0)
90 config_file_path_ = path + executable;
91 else
92 config_file_path_ = instance_path + executable;
93 std::ifstream file_stream(config_file_path_,
94 std::ios::in | std::ios::ate | std::ios::binary);
95 if (!file_stream.is_open()) return;
96 file_present_ = true;
97 {
98 /* Check if files read-only or not */
99 std::ofstream out_stream(config_file_path_, std::ios_base::app);
100 ro_ = !out_stream.is_open();
101 out_stream.close();
102 }
103 auto clean_up = create_scope_guard([&] { file_stream.close(); });
104 auto file_length = file_stream.tellg();
105 if (file_length > 0) {
106 empty_ = false;
107 file_stream.seekg(std::ios::beg);
108 std::unique_ptr<char[]> read_data(new (std::nothrow) char[file_length]);
109 if (!read_data) return;
110 if (file_stream.read(read_data.get(), file_length).fail() == true) return;
111 std::string data(read_data.get(), file_length);
112 if (data_.Parse(data).HasParseError()) return;
113 if (schema_.Parse(json_schema).HasParseError()) return;
114 {
115 rapidjson::Document document;
116 if (document.Parse(data).HasParseError()) return;
117
118 rapidjson::SchemaDocument sd(schema_);
119 rapidjson::SchemaValidator validator(sd);
120 if (!document.Accept(validator)) return;
121 }
122 }
123 valid_ = true;
124 }
125
126 ~Manifest_reader() = default;
127
128 bool file_present() const { return file_present_; }
129 bool empty() const { return !file_present_ || empty_; }
130 bool ro() const { return ro_; }
131 std::string manifest_file() const { return config_file_path_; }
132
133 bool read_local_manifest() const {
134 bool read_local_manifest = false;
135 if (get_element<bool>("read_local_manifest", read_local_manifest) == false)
136 return false;
137 return read_local_manifest;
138 }
139
140 bool components(std::string &components_string) const {
141 return get_element<std::string>("components", components_string);
142 }
143
144 private:
145 /**
146 Get an element value from JSON document.
147 Assumption: Type is compatible with Get() function and
148 type of element is matching with template argument.
149
150 @param [in] element_name Name of the element being searched
151 @param [out] element_value Value of the element
152
153 @returns status of search operation
154 @retval true Element found. Refer to element_value
155 @retval false Element missing.
156 */
157
158 template <typename T>
159 bool get_element(const std::string element_name, T &element_value) const {
160 if (!valid_ || !data_.HasMember(element_name)) return false;
161 element_value = data_[element_name].Get<T>();
162 return true;
163 }
164
165 private:
166 /** Configuration file path */
167 std::string config_file_path_;
168 /** Schema Document */
169 rapidjson::Document schema_;
170 /** Configuration data in JSON */
171 rapidjson::Document data_;
172 /** File status */
174 /** Validity of configuration data */
175 bool valid_;
176 /** content */
177 bool empty_;
178 /** RO flag */
179 bool ro_;
180};
181
182} // namespace manifest
183
184#endif // !MANIFEST_INCLUDED
Definition: manifest.h:57
bool ro() const
Definition: manifest.h:130
bool file_present() const
Definition: manifest.h:128
bool components(std::string &components_string) const
Definition: manifest.h:140
Manifest_reader(const std::string executable_path, const std::string instance_path, std::string json_schema=manifest_version_1_0)
Definition: manifest.h:70
bool empty() const
Definition: manifest.h:129
bool get_element(const std::string element_name, T &element_value) const
Get an element value from JSON document.
Definition: manifest.h:159
bool empty_
content
Definition: manifest.h:177
bool read_local_manifest() const
Definition: manifest.h:133
bool ro_
RO flag.
Definition: manifest.h:179
std::string config_file_path_
Configuration file path.
Definition: manifest.h:167
rapidjson::Document data_
Configuration data in JSON.
Definition: manifest.h:171
bool valid_
Validity of configuration data.
Definition: manifest.h:175
std::string manifest_file() const
Definition: manifest.h:131
rapidjson::Document schema_
Schema Document.
Definition: manifest.h:169
bool file_present_
File status.
Definition: manifest.h:173
Define rapidjson::SizeType to be std::size_t.
static void clean_up(bool print_message)
Definition: mysqld.cc:2535
static char * path
Definition: mysqldump.cc:133
constexpr value_type binary
Definition: classic_protocol_constants.h:270
Json_data_extension ext
Definition: backend.cc:50
Definition: manifest.h:36
std::string manifest_version_1_0
Definition: manifest.h:38
Scope_guard< TLambda > create_scope_guard(const TLambda rollback_lambda)
Definition: scope_guard.h:60