OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JsonUtils.h
Go to the documentation of this file.
1 /*
2  * Copyright 2023 HEAVY.AI, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <map>
20 #include <optional>
21 #include <vector>
22 
23 #include <rapidjson/document.h>
24 
25 #include "Logger/Logger.h"
26 #include "Shared/sqltypes.h"
27 
28 // helper functions for serializing/deserializing objects to rapidjson value
29 namespace json_utils {
30 std::string get_type_as_string(const rapidjson::Value& object);
31 
32 // Forward declare for vector/map functions
33 template <class T>
34 void add_value_to_object(rapidjson::Value& object,
35  const T& value,
36  const std::string& name,
37  rapidjson::Document::AllocatorType& allocator);
38 template <class T>
39 void get_value_from_object(const rapidjson::Value& object,
40  T& value,
41  const std::string& name);
42 
43 std::optional<std::string> get_optional_string_value_from_object(
44  const rapidjson::Value& object,
45  const std::string& name);
46 
47 // Basic types (more can be added as required) will be defined in source file
48 // int
49 void set_value(rapidjson::Value& json_val,
50  const size_t& value,
51  rapidjson::Document::AllocatorType& allocator);
52 void get_value(const rapidjson::Value& json_val, size_t& value);
53 // unsigned long int / size_t
54 void set_value(rapidjson::Value& json_val,
55  const int& value,
56  rapidjson::Document::AllocatorType& allocator);
57 void get_value(const rapidjson::Value& json_val, int& value);
58 // string
59 void set_value(rapidjson::Value& json_val,
60  const std::string& value,
61  rapidjson::Document::AllocatorType& allocator);
62 void get_value(const rapidjson::Value& json_val, std::string& value);
63 
64 // int64
65 void set_value(rapidjson::Value& json_val,
66  const int64_t& value,
67  rapidjson::Document::AllocatorType& allocator);
68 
69 void get_value(const rapidjson::Value& json_val, int64_t& value);
70 
71 // bool
72 void set_value(rapidjson::Value& json_val,
73  const bool& value,
74  rapidjson::Document::AllocatorType& allocator);
75 
76 void get_value(const rapidjson::Value& json_val, bool& value);
77 
78 // SQLTypes
79 void set_value(rapidjson::Value& json_val,
80  const SQLTypes& value,
81  rapidjson::Document::AllocatorType& allocator);
82 
83 void get_value(const rapidjson::Value& json_val, SQLTypes& value);
84 
85 // EncodingType
86 void set_value(rapidjson::Value& json_val,
87  const EncodingType& column_desc,
88  rapidjson::Document::AllocatorType& allocator);
89 
90 void get_value(const rapidjson::Value& json_val, EncodingType& column_desc);
91 
92 // StringDictKey
93 void set_value(rapidjson::Value& json_val,
94  const shared::StringDictKey& dict_key,
95  rapidjson::Document::AllocatorType& allocator);
96 
97 void get_value(const rapidjson::Value& json_val, shared::StringDictKey& dict_key);
98 
99 // SQLTypeInfo
100 void set_value(rapidjson::Value& json_val,
101  const SQLTypeInfo& type_info,
102  rapidjson::Document::AllocatorType& allocator);
103 
104 template <typename T, typename MemberFunc>
105 void get_value_from_object(const rapidjson::Value& json_val,
106  MemberFunc mem_fn,
107  SQLTypeInfo& type_info,
108  const std::string& key) {
109  T value;
110  auto setter = std::bind(mem_fn, &type_info, std::placeholders::_1);
111  get_value_from_object(json_val, value, key);
112  setter(value);
113 }
114 
115 void get_value(const rapidjson::Value& json_val, SQLTypeInfo& type_info);
116 
117 // std::vector
118 template <class T>
119 void set_value(rapidjson::Value& json_val,
120  const std::vector<T>& vector_value,
121  rapidjson::Document::AllocatorType& allocator) {
122  json_val.SetArray();
123  for (const auto& value : vector_value) {
124  rapidjson::Value json_obj;
125  set_value(json_obj, value, allocator);
126  json_val.PushBack(json_obj, allocator);
127  }
128 }
129 
130 template <class T>
131 void get_value(const rapidjson::Value& json_val, std::vector<T>& vector_value) {
132  CHECK(json_val.IsArray());
133  CHECK_EQ(vector_value.size(), size_t(0));
134  for (const auto& json_obj : json_val.GetArray()) {
135  T val;
136  get_value(json_obj, val);
137  vector_value.push_back(val);
138  }
139 }
140 
141 // std::list
142 template <class T>
143 void set_value(rapidjson::Value& json_val,
144  const std::list<T>& list_value,
145  rapidjson::Document::AllocatorType& allocator) {
146  json_val.SetArray();
147  for (const auto& value : list_value) {
148  rapidjson::Value json_obj;
149  set_value(json_obj, value, allocator);
150  json_val.PushBack(json_obj, allocator);
151  }
152 }
153 
154 template <class T>
155 void get_value(const rapidjson::Value& json_val, std::list<T>& list_value) {
156  CHECK(json_val.IsArray());
157  CHECK_EQ(list_value.size(), size_t(0));
158  for (const auto& json_obj : json_val.GetArray()) {
159  T val;
160  get_value(json_obj, val);
161  list_value.push_back(val);
162  }
163 }
164 
165 // std::vector<std::pair>
166 template <class T, class V>
167 void set_value(rapidjson::Value& json_val,
168  const std::vector<std::pair<T, V>>& vector_value,
169  rapidjson::Document::AllocatorType& allocator) {
170  json_val.SetArray();
171  for (const auto& pair : vector_value) {
172  rapidjson::Value pair_obj;
173  pair_obj.SetObject();
174  add_value_to_object(pair_obj, pair.first, "key", allocator);
175  add_value_to_object(pair_obj, pair.second, "value", allocator);
176  json_val.PushBack(pair_obj, allocator);
177  }
178 }
179 
180 template <class T, class V>
181 void get_value(const rapidjson::Value& json_val,
182  std::vector<std::pair<T, V>>& vector_value) {
183  CHECK(json_val.IsArray());
184  CHECK_EQ(vector_value.size(), size_t(0));
185  for (const auto& json_obj : json_val.GetArray()) {
186  CHECK(json_obj.IsObject());
187  T key;
188  V value;
189  get_value_from_object(json_obj, key, "key");
190  get_value_from_object(json_obj, value, "value");
191  vector_value.emplace_back(std::make_pair(key, value));
192  }
193 }
194 
195 // std::list<std::pair>
196 template <class T, class V>
197 void set_value(rapidjson::Value& json_val,
198  const std::list<std::pair<T, V>>& list_value,
199  rapidjson::Document::AllocatorType& allocator) {
200  json_val.SetArray();
201  for (const auto& pair : list_value) {
202  rapidjson::Value pair_obj;
203  pair_obj.SetObject();
204  add_value_to_object(pair_obj, pair.first, "key", allocator);
205  add_value_to_object(pair_obj, pair.second, "value", allocator);
206  json_val.PushBack(pair_obj, allocator);
207  }
208 }
209 
210 template <class T, class V>
211 void get_value(const rapidjson::Value& json_val, std::list<std::pair<T, V>>& list_value) {
212  CHECK(json_val.IsArray());
213  CHECK_EQ(list_value.size(), size_t(0));
214  for (const auto& json_obj : json_val.GetArray()) {
215  CHECK(json_obj.IsObject());
216  T key;
217  V value;
218  get_value_from_object(json_obj, key, "key");
219  get_value_from_object(json_obj, value, "value");
220  list_value.emplace_back(std::make_pair(key, value));
221  }
222 }
223 
224 // std::map
225 template <class T, class V>
226 void set_value(rapidjson::Value& json_val,
227  const std::map<T, V>& map_value,
228  rapidjson::Document::AllocatorType& allocator) {
229  json_val.SetArray();
230  for (const auto& pair : map_value) {
231  rapidjson::Value pair_obj;
232  pair_obj.SetObject();
233  add_value_to_object(pair_obj, pair.first, "key", allocator);
234  add_value_to_object(pair_obj, pair.second, "value", allocator);
235  json_val.PushBack(pair_obj, allocator);
236  }
237 }
238 
239 template <class T, class V>
240 void get_value(const rapidjson::Value& json_val, std::map<T, V>& map_value) {
241  CHECK(json_val.IsArray());
242  CHECK_EQ(map_value.size(), size_t(0));
243  for (const auto& json_obj : json_val.GetArray()) {
244  CHECK(json_obj.IsObject());
245  T key;
246  V value;
247  get_value_from_object(json_obj, key, "key");
248  get_value_from_object(json_obj, value, "value");
249  map_value[key] = value;
250  }
251 }
252 
253 // Serialize value into json object with valid set_value functions
254 template <class T>
255 void add_value_to_object(rapidjson::Value& object,
256  const T& value,
257  const std::string& name,
258  rapidjson::Document::AllocatorType& allocator) {
259  CHECK(object.IsObject());
260  CHECK(!object.HasMember(name)) << "Found unexpected member: " << name;
261  rapidjson::Value json_val;
262  set_value(json_val, value, allocator);
263  rapidjson::Value json_name;
264  json_name.SetString(name, allocator);
265  object.AddMember(json_name, json_val, allocator);
266 }
267 
268 // Deserialize value from json object with valid get_value/set_value functions
269 template <class T>
270 void get_value_from_object(const rapidjson::Value& object,
271  T& value,
272  const std::string& name) {
273  CHECK(object.IsObject());
274  CHECK(object.HasMember(name)) << "Could not find member: " << name;
275  get_value(object[name], value);
276 }
277 
278 // Read JSON content from the given file path
279 rapidjson::Document read_from_file(const std::string& file_path);
280 
281 // Write JSON content (encapsulated by the given Document object) to the given file path
282 void write_to_file(const rapidjson::Document& document, const std::string& file_path);
283 
284 std::string write_to_string(const rapidjson::Document& document);
285 
286 } // namespace json_utils
#define CHECK_EQ(x, y)
Definition: Logger.h:301
SQLTypes
Definition: sqltypes.h:65
void set_value(rapidjson::Value &json_val, const ColumnDescriptor &column_desc, rapidjson::Document::AllocatorType &allocator)
void write_to_file(const rapidjson::Document &document, const std::string &filepath)
Definition: JsonUtils.cpp:214
void get_value_from_object(const rapidjson::Value &object, T &value, const std::string &name)
Definition: JsonUtils.h:270
Constants for Builtin SQL Types supported by HEAVY.AI.
rapidjson::Document read_from_file(const std::string &file_path)
Definition: JsonUtils.cpp:201
EncodingType
Definition: sqltypes.h:240
std::optional< std::string > get_optional_string_value_from_object(const rapidjson::Value &object, const std::string &key)
Definition: JsonUtils.cpp:232
std::string write_to_string(const rapidjson::Document &document)
Definition: JsonUtils.cpp:225
std::string get_type_as_string(const rapidjson::Value &object)
Definition: JsonUtils.cpp:29
void get_value(const rapidjson::Value &json_val, ColumnDescriptor &column_desc)
void add_value_to_object(rapidjson::Value &object, const T &value, const std::string &name, rapidjson::Document::AllocatorType &allocator)
Definition: JsonUtils.h:255
#define CHECK(condition)
Definition: Logger.h:291
string name
Definition: setup.in.py:72