MySQL  8.0.26
Source Code Documentation
manifest.h
Go to the documentation of this file.
1 /* Copyright (c) 2021, 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 
36 namespace manifest {
37 
38 std::string manifest_version_1_0 =
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 
57 class 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] use_cwd Use current working directory as base location
67  */
68 
69  explicit Manifest_reader(const std::string executable_path,
70  bool use_cwd = false,
71  std::string json_schema = manifest_version_1_0)
73  schema_(),
74  data_(),
75  file_present_(false),
76  valid_(false),
77  empty_(true),
78  ro_(true) {
79  std::string exe_path(executable_path);
80  std::size_t last_separator = exe_path.find_last_of("/\\");
81  std::string executable = exe_path.substr(last_separator + 1);
82  std::string path = exe_path.erase(last_separator + 1);
83 #ifdef _WIN32
84  std::size_t ext = executable.find(".exe");
85  executable = executable.substr(0, ext);
86 #endif // _WIN32
87  executable.append(".my");
88  if (!use_cwd)
89  config_file_path_ = path + executable;
90  else
91  config_file_path_ = executable;
92  std::ifstream file_stream(config_file_path_, std::ios::in | std::ios::ate);
93  if (!file_stream.is_open()) return;
94  file_present_ = true;
95  {
96  /* Check if files read-only or not */
97  std::ofstream out_stream(config_file_path_, std::ios_base::app);
98  ro_ = !out_stream.is_open();
99  out_stream.close();
100  }
101  auto clean_up = create_scope_guard([&] { file_stream.close(); });
102  auto file_length = file_stream.tellg();
103  if (file_length > 0) {
104  empty_ = false;
105  file_stream.seekg(std::ios::beg);
106  std::unique_ptr<char[]> read_data(new (std::nothrow) char[file_length]);
107  if (!read_data) return;
108  if (file_stream.read(read_data.get(), file_length).fail() == true) return;
109  std::string data(read_data.get(), file_length);
110  if (data_.Parse(data).HasParseError()) return;
111  if (schema_.Parse(json_schema).HasParseError()) return;
112  {
113  rapidjson::Document document;
114  if (document.Parse(data).HasParseError()) return;
115 
116  rapidjson::SchemaDocument sd(schema_);
117  rapidjson::SchemaValidator validator(sd);
118  if (!document.Accept(validator)) return;
119  }
120  }
121  valid_ = true;
122  }
123 
124  ~Manifest_reader() = default;
125 
126  bool file_present() const { return file_present_; }
127  bool empty() const { return !file_present_ || empty_; }
128  bool ro() const { return ro_; }
129  std::string manifest_file() const { return config_file_path_; }
130 
131  bool read_local_manifest() const {
132  bool read_local_manifest = false;
133  if (get_element<bool>("read_local_manifest", read_local_manifest) == false)
134  return false;
135  return read_local_manifest;
136  }
137 
138  bool components(std::string &components_string) const {
139  return get_element<std::string>("components", components_string);
140  }
141 
142  private:
143  /**
144  Get an element value from JSON document.
145  Assumption: Type is compatible with Get() function and
146  type of element is matching with template argument.
147 
148  @param [in] element_name Name of the element being searched
149  @param [out] element_value Value of the element
150 
151  @returns status of search operation
152  @retval true Element found. Refer to element_value
153  @retval false Element missing.
154  */
155 
156  template <typename T>
157  bool get_element(const std::string element_name, T &element_value) const {
158  if (!valid_ || !data_.HasMember(element_name)) return false;
159  element_value = data_[element_name].Get<T>();
160  return true;
161  }
162 
163  private:
164  /** Configuration file path */
165  std::string config_file_path_;
166  /** Schema Document */
167  rapidjson::Document schema_;
168  /** Configuration data in JSON */
169  rapidjson::Document data_;
170  /** File status */
172  /** Validity of configuration data */
173  bool valid_;
174  /** content */
175  bool empty_;
176  /** RO flag */
177  bool ro_;
178 };
179 
180 } // namespace manifest
181 
182 #endif // !MANIFEST_INCLUDED
Definition: manifest.h:57
bool ro() const
Definition: manifest.h:128
Manifest_reader(const std::string executable_path, bool use_cwd=false, std::string json_schema=manifest_version_1_0)
Definition: manifest.h:69
bool file_present() const
Definition: manifest.h:126
bool components(std::string &components_string) const
Definition: manifest.h:138
bool empty() const
Definition: manifest.h:127
bool get_element(const std::string element_name, T &element_value) const
Get an element value from JSON document.
Definition: manifest.h:157
bool empty_
content
Definition: manifest.h:175
bool read_local_manifest() const
Definition: manifest.h:131
bool ro_
RO flag.
Definition: manifest.h:177
std::string config_file_path_
Configuration file path.
Definition: manifest.h:165
rapidjson::Document data_
Configuration data in JSON.
Definition: manifest.h:169
bool valid_
Validity of configuration data.
Definition: manifest.h:173
std::string manifest_file() const
Definition: manifest.h:129
rapidjson::Document schema_
Schema Document.
Definition: manifest.h:167
bool file_present_
File status.
Definition: manifest.h:171
Define rapidjson::SizeType to be std::size_t.
static void clean_up(bool print_message)
Definition: mysqld.cc:2479
static char * path
Definition: mysqldump.cc:132
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