Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
database_protocol_container.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#ifdef USE_CONTAINER_SYSTEM
6
8#include <core/container.h>
9#include <core/value_types.h>
10
11namespace database::protocol {
12
13using namespace container_module;
14
15std::vector<uint8_t> container_protocol_serializer::serialize_container(
16 const query_request& request) {
17 // Create container
18 auto container = std::make_shared<value_container>();
19 container->set_message_type("query_request");
20
21 // Serialize operation (as int since uint8 is promoted to int in variant)
22 container->set("operation", static_cast<int>(request.operation));
23
24 // Serialize query_string
25 container->set("query_string", std::string(request.query_string));
26
27 // Serialize parameters count
28 container->set("param_count", static_cast<unsigned int>(request.parameters.size()));
29
30 // Serialize each parameter
31 for (size_t i = 0; i < request.parameters.size(); ++i) {
32 std::string param_key = "param_" + std::to_string(i);
33 container->set(param_key, std::string(request.parameters[i]));
34 }
35
36 // Serialize to bytes
37 auto result = container->serialize(value_container::serialization_format::binary);
38 if (result.is_ok()) {
39 return result.value();
40 }
41 return {};
42}
43
44kcenon::common::Result<query_request> container_protocol_serializer::deserialize_container_query_request(
45 const std::vector<uint8_t>& data) {
46 try {
47 // Create container from bytes
48 auto container = std::make_shared<value_container>(data, false);
49
50 // Validate message type
51 if (container->message_type() != "query_request") {
52 return kcenon::common::error_info{
53 static_cast<int>(error_code::invalid_argument),
54 "Invalid message type: " + container->message_type(),
55 "database_protocol"};
56 }
57
58 query_request request;
59
60 // Deserialize operation
61 auto operation_val = container->get("operation");
62 if (operation_val.has_value()) {
63 if (std::holds_alternative<int>(operation_val->data)) {
64 request.operation = static_cast<query_operation>(
65 std::get<int>(operation_val->data));
66 } else {
67 return kcenon::common::error_info{
68 static_cast<int>(error_code::invalid_argument),
69 "Invalid operation field type",
70 "database_protocol"};
71 }
72 } else {
73 return kcenon::common::error_info{
74 static_cast<int>(error_code::invalid_argument),
75 "Missing operation field",
76 "database_protocol"};
77 }
78
79 // Deserialize query_string
80 auto query_val = container->get("query_string");
81 if (query_val.has_value()) {
82 if (std::holds_alternative<std::string>(query_val->data)) {
83 request.query_string = std::get<std::string>(query_val->data);
84 } else {
85 return kcenon::common::error_info{
86 static_cast<int>(error_code::invalid_argument),
87 "Invalid query_string field type",
88 "database_protocol"};
89 }
90 } else {
91 return kcenon::common::error_info{
92 static_cast<int>(error_code::invalid_argument),
93 "Missing query_string field",
94 "database_protocol"};
95 }
96
97 // Deserialize parameters count
98 auto param_count_val = container->get("param_count");
99 if (param_count_val.has_value()) {
100 if (std::holds_alternative<unsigned int>(param_count_val->data)) {
101 uint32_t count = std::get<unsigned int>(param_count_val->data);
102 request.parameters.reserve(count);
103
104 // Deserialize each parameter
105 for (uint32_t i = 0; i < count; ++i) {
106 std::string param_key = "param_" + std::to_string(i);
107 auto param_val = container->get(param_key);
108 if (param_val.has_value()) {
109 if (std::holds_alternative<std::string>(param_val->data)) {
110 request.parameters.push_back(std::get<std::string>(param_val->data));
111 } else {
112 return kcenon::common::error_info{
113 static_cast<int>(error_code::invalid_argument),
114 "Invalid parameter type at index " + std::to_string(i),
115 "database_protocol"};
116 }
117 } else {
118 return kcenon::common::error_info{
119 static_cast<int>(error_code::invalid_argument),
120 "Missing parameter at index " + std::to_string(i),
121 "database_protocol"};
122 }
123 }
124 } else {
125 return kcenon::common::error_info{
126 static_cast<int>(error_code::invalid_argument),
127 "Invalid param_count field type",
128 "database_protocol"};
129 }
130 } else {
131 return kcenon::common::error_info{
132 static_cast<int>(error_code::invalid_argument),
133 "Missing param_count field",
134 "database_protocol"};
135 }
136
137 return request;
138 } catch (const std::exception& e) {
139 return kcenon::common::error_info{
140 static_cast<int>(error_code::invalid_argument),
141 std::string("Deserialization exception: ") + e.what(),
142 "database_protocol"};
143 }
144}
145
146std::string container_protocol_serializer::serialize_to_json(const query_request& request) {
147 // Create container
148 auto container = std::make_shared<value_container>();
149 container->set_message_type("query_request");
150
151 // Serialize fields using template set for automatic type deduction
152 container->set("operation", static_cast<int>(request.operation));
153 container->set("query_string", std::string(request.query_string));
154 container->set("param_count", static_cast<unsigned int>(request.parameters.size()));
155
156 for (size_t i = 0; i < request.parameters.size(); ++i) {
157 std::string param_key = "param_" + std::to_string(i);
158 container->set(param_key, std::string(request.parameters[i]));
159 }
160
161 // Serialize to JSON
162 auto result = container->serialize_string(value_container::serialization_format::json);
163 if (result.is_ok()) {
164 return result.value();
165 }
166 return {};
167}
168
169} // namespace database::protocol
170
171#endif // USE_CONTAINER_SYSTEM
query_operation
Type of query operation.