Skip to content

Commit 7531e29

Browse files
committed
first version
1 parent b830c93 commit 7531e29

File tree

8 files changed

+1073
-181
lines changed

8 files changed

+1073
-181
lines changed

src/iceberg/catalog/rest/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
set(ICEBERG_REST_SOURCES rest_catalog.cc)
18+
set(ICEBERG_REST_SOURCES rest_catalog.cc json_internal.cc)
1919

2020
set(ICEBERG_REST_STATIC_BUILD_INTERFACE_LIBS)
2121
set(ICEBERG_REST_SHARED_BUILD_INTERFACE_LIBS)
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "iceberg/catalog/rest/json_internal.h"
21+
22+
#include <string>
23+
#include <unordered_map>
24+
#include <vector>
25+
26+
#include <nlohmann/json.hpp>
27+
28+
#include "iceberg/json_internal.h"
29+
#include "iceberg/partition_spec.h"
30+
#include "iceberg/result.h"
31+
#include "iceberg/schema.h"
32+
#include "iceberg/sort_order.h"
33+
#include "iceberg/table_identifier.h"
34+
#include "iceberg/table_metadata.h"
35+
#include "iceberg/util/json_util_internal.h"
36+
#include "iceberg/util/macros.h"
37+
38+
namespace iceberg::rest {
39+
40+
namespace {
41+
42+
// REST API JSON field constants
43+
constexpr std::string_view kNamespaces = "namespaces";
44+
constexpr std::string_view kRemovals = "removals";
45+
constexpr std::string_view kUpdates = "updates";
46+
constexpr std::string_view kUpdated = "updated";
47+
constexpr std::string_view kRemoved = "removed";
48+
constexpr std::string_view kMissing = "missing";
49+
constexpr std::string_view kIdentifiers = "identifiers";
50+
constexpr std::string_view kSource = "source";
51+
constexpr std::string_view kDestination = "destination";
52+
constexpr std::string_view kMetadataLocation = "metadata-location";
53+
constexpr std::string_view kMetadata = "metadata";
54+
constexpr std::string_view kConfig = "config";
55+
constexpr std::string_view kName = "name";
56+
constexpr std::string_view kLocation = "location";
57+
constexpr std::string_view kSchema = "schema";
58+
constexpr std::string_view kPartitionSpec = "partition-spec";
59+
constexpr std::string_view kWriteOrder = "write-order";
60+
constexpr std::string_view kStageCreate = "stage-create";
61+
constexpr std::string_view kProperties = "properties";
62+
constexpr std::string_view kOverwrite = "overwrite";
63+
constexpr std::string_view kNamespace = "namespace";
64+
65+
/// Helper function to convert TableIdentifier to JSON
66+
nlohmann::json TableIdentifierToJson(const TableIdentifier& identifier) {
67+
nlohmann::json json;
68+
json[kNamespace] = identifier.ns.levels;
69+
json[kName] = identifier.name;
70+
return json;
71+
}
72+
73+
/// Helper function to parse TableIdentifier from JSON
74+
Result<TableIdentifier> TableIdentifierFromJson(const nlohmann::json& json) {
75+
TableIdentifier identifier;
76+
77+
if (json.contains(kNamespace)) {
78+
ICEBERG_ASSIGN_OR_RAISE(identifier.ns.levels,
79+
GetJsonValue<std::vector<std::string>>(json, kNamespace));
80+
}
81+
82+
ICEBERG_ASSIGN_OR_RAISE(identifier.name, GetJsonValue<std::string>(json, kName));
83+
84+
return identifier;
85+
}
86+
87+
} // namespace
88+
89+
nlohmann::json ToJson(const ListNamespaceResponse& response) {
90+
nlohmann::json json;
91+
json[kNamespaces] = response.namespaces;
92+
return json;
93+
}
94+
95+
Result<ListNamespaceResponse> ListNamespaceResponseFromJson(const nlohmann::json& json) {
96+
ListNamespaceResponse response;
97+
98+
ICEBERG_ASSIGN_OR_RAISE(
99+
response.namespaces,
100+
GetJsonValue<std::vector<std::vector<std::string>>>(json, kNamespaces));
101+
return response;
102+
}
103+
104+
nlohmann::json ToJson(const UpdateNamespacePropsRequest& request) {
105+
nlohmann::json json;
106+
SetOptionalField(json, kRemovals, request.removals);
107+
SetOptionalField(json, kUpdates, request.updates);
108+
return json;
109+
}
110+
111+
Result<UpdateNamespacePropsRequest> UpdateNamespacePropsRequestFromJson(
112+
const nlohmann::json& json) {
113+
UpdateNamespacePropsRequest request;
114+
115+
ICEBERG_ASSIGN_OR_RAISE(
116+
request.removals, GetJsonValueOptional<std::vector<std::string>>(json, kRemovals));
117+
using MapType = std::unordered_map<std::string, std::string>;
118+
ICEBERG_ASSIGN_OR_RAISE(request.updates, GetJsonValueOptional<MapType>(json, kUpdates));
119+
120+
return request;
121+
}
122+
123+
nlohmann::json ToJson(const UpdateNamespacePropsResponse& response) {
124+
nlohmann::json json;
125+
json[kUpdated] = response.updated;
126+
json[kRemoved] = response.removed;
127+
SetOptionalField(json, kMissing, response.missing);
128+
return json;
129+
}
130+
131+
Result<UpdateNamespacePropsResponse> UpdateNamespacePropsResponseFromJson(
132+
const nlohmann::json& json) {
133+
UpdateNamespacePropsResponse response;
134+
135+
ICEBERG_ASSIGN_OR_RAISE(response.updated,
136+
GetJsonValue<std::vector<std::string>>(json, kUpdated));
137+
ICEBERG_ASSIGN_OR_RAISE(response.removed,
138+
GetJsonValue<std::vector<std::string>>(json, kRemoved));
139+
ICEBERG_ASSIGN_OR_RAISE(response.missing,
140+
GetJsonValueOptional<std::vector<std::string>>(json, kMissing));
141+
142+
return response;
143+
}
144+
145+
nlohmann::json ToJson(const ListTableResponse& response) {
146+
nlohmann::json json;
147+
148+
nlohmann::json identifiers_json = nlohmann::json::array();
149+
for (const auto& identifier : response.identifiers) {
150+
identifiers_json.push_back(TableIdentifierToJson(identifier));
151+
}
152+
json[kIdentifiers] = identifiers_json;
153+
return json;
154+
}
155+
156+
Result<ListTableResponse> ListTableResponseFromJson(const nlohmann::json& json) {
157+
ListTableResponse response;
158+
159+
ICEBERG_ASSIGN_OR_RAISE(auto identifiers_json,
160+
GetJsonValue<nlohmann::json>(json, kIdentifiers));
161+
162+
for (const auto& id_json : identifiers_json) {
163+
ICEBERG_ASSIGN_OR_RAISE(auto identifier, TableIdentifierFromJson(id_json));
164+
response.identifiers.push_back(std::move(identifier));
165+
}
166+
return response;
167+
}
168+
169+
nlohmann::json ToJson(const RenameTableRequest& request) {
170+
nlohmann::json json;
171+
json[kSource] = TableIdentifierToJson(request.source);
172+
json[kDestination] = TableIdentifierToJson(request.destination);
173+
return json;
174+
}
175+
176+
Result<RenameTableRequest> RenameTableRequestFromJson(const nlohmann::json& json) {
177+
RenameTableRequest request;
178+
179+
ICEBERG_ASSIGN_OR_RAISE(auto source_json, GetJsonValue<nlohmann::json>(json, kSource));
180+
ICEBERG_ASSIGN_OR_RAISE(request.source, TableIdentifierFromJson(source_json));
181+
182+
ICEBERG_ASSIGN_OR_RAISE(auto dest_json,
183+
GetJsonValue<nlohmann::json>(json, kDestination));
184+
ICEBERG_ASSIGN_OR_RAISE(request.destination, TableIdentifierFromJson(dest_json));
185+
186+
return request;
187+
}
188+
189+
nlohmann::json ToJson(const LoadTableResponse& response) {
190+
nlohmann::json json;
191+
192+
SetOptionalField(json, kMetadataLocation, response.metadata_location);
193+
json[kMetadata] = iceberg::ToJson(response.metadata);
194+
SetOptionalField(json, kConfig, response.config);
195+
196+
return json;
197+
}
198+
199+
Result<LoadTableResponse> LoadTableResponseFromJson(const nlohmann::json& json) {
200+
LoadTableResponse response;
201+
202+
ICEBERG_ASSIGN_OR_RAISE(response.metadata_location,
203+
GetJsonValueOptional<std::string>(json, kMetadataLocation));
204+
205+
ICEBERG_ASSIGN_OR_RAISE(auto metadata_json,
206+
GetJsonValue<nlohmann::json>(json, kMetadata));
207+
ICEBERG_ASSIGN_OR_RAISE(auto metadata_ptr,
208+
iceberg::TableMetadataFromJson(metadata_json));
209+
response.metadata = std::move(*metadata_ptr);
210+
211+
using MapType = std::unordered_map<std::string, std::string>;
212+
ICEBERG_ASSIGN_OR_RAISE(response.config, GetJsonValueOptional<MapType>(json, kConfig));
213+
214+
return response;
215+
}
216+
217+
nlohmann::json ToJson(const CreateTableRequest& request) {
218+
nlohmann::json json;
219+
json[kName] = request.name;
220+
SetOptionalField(json, kLocation, request.location);
221+
json[kSchema] = ToJson(*request.schema);
222+
223+
if (request.partition_spec) {
224+
json[kPartitionSpec] = ToJson(*request.partition_spec);
225+
}
226+
227+
if (request.write_order) {
228+
json[kWriteOrder] = ToJson(*request.write_order);
229+
}
230+
231+
SetOptionalField(json, kStageCreate, request.stage_create);
232+
SetOptionalField(json, kProperties, request.properties);
233+
return json;
234+
}
235+
236+
Result<CreateTableRequest> CreateTableRequestFromJson(const nlohmann::json& json) {
237+
CreateTableRequest request;
238+
239+
// Parse required fields
240+
ICEBERG_ASSIGN_OR_RAISE(request.name, GetJsonValue<std::string>(json, kName));
241+
242+
// Parse optional location
243+
ICEBERG_ASSIGN_OR_RAISE(request.location,
244+
GetJsonValueOptional<std::string>(json, kLocation));
245+
246+
// Parse required schema
247+
ICEBERG_ASSIGN_OR_RAISE(auto schema_json, GetJsonValue<nlohmann::json>(json, kSchema));
248+
ICEBERG_ASSIGN_OR_RAISE(auto schema_ptr, iceberg::SchemaFromJson(schema_json));
249+
request.schema = std::move(schema_ptr);
250+
251+
if (json.contains(kPartitionSpec)) {
252+
ICEBERG_ASSIGN_OR_RAISE(auto partition_spec_json,
253+
GetJsonValue<nlohmann::json>(json, kPartitionSpec));
254+
ICEBERG_ASSIGN_OR_RAISE(
255+
request.partition_spec,
256+
iceberg::PartitionSpecFromJson(request.schema, partition_spec_json));
257+
} else {
258+
request.partition_spec = nullptr;
259+
}
260+
261+
if (json.contains(kWriteOrder)) {
262+
ICEBERG_ASSIGN_OR_RAISE(auto write_order_json,
263+
GetJsonValue<nlohmann::json>(json, kWriteOrder));
264+
ICEBERG_ASSIGN_OR_RAISE(request.write_order,
265+
iceberg::SortOrderFromJson(write_order_json));
266+
} else {
267+
request.write_order = nullptr;
268+
}
269+
270+
ICEBERG_ASSIGN_OR_RAISE(request.stage_create,
271+
GetJsonValueOptional<bool>(json, kStageCreate));
272+
273+
using MapType = std::unordered_map<std::string, std::string>;
274+
ICEBERG_ASSIGN_OR_RAISE(request.properties,
275+
GetJsonValueOptional<MapType>(json, kProperties));
276+
277+
return request;
278+
}
279+
280+
nlohmann::json ToJson(const RegisterTableRequest& request) {
281+
nlohmann::json json;
282+
json[kName] = request.name;
283+
json[kMetadataLocation] = request.metadata_location;
284+
SetOptionalField(json, kOverwrite, request.overwrite);
285+
return json;
286+
}
287+
288+
Result<RegisterTableRequest> RegisterTableRequestFromJson(const nlohmann::json& json) {
289+
RegisterTableRequest request;
290+
291+
ICEBERG_ASSIGN_OR_RAISE(request.name, GetJsonValue<std::string>(json, kName));
292+
ICEBERG_ASSIGN_OR_RAISE(request.metadata_location,
293+
GetJsonValue<std::string>(json, kMetadataLocation));
294+
ICEBERG_ASSIGN_OR_RAISE(request.overwrite,
295+
GetJsonValueOptional<bool>(json, kOverwrite));
296+
297+
return request;
298+
}
299+
300+
} // namespace iceberg::rest

0 commit comments

Comments
 (0)