Blink DB Documentation v1.0.0
Blink DB Documentation
Loading...
Searching...
No Matches
command_parser.hpp
Go to the documentation of this file.
1
10#ifndef COMMAND_PARSER_HPP
11#define COMMAND_PARSER_HPP
12
13#include "engine/lsm.hpp"
14#include "resp_encoder.hpp"
15#include <string>
16#include <utility>
17#include <vector>
18
28public:
32 bool success;
36 std::string errmsg;
40 std::string key;
44 std::string value;
48 ValidationResult() : success(false), errmsg(""), key(""), value("") {}
49};
50
59private:
69 static std::vector<std::string> split(const std::string &str) {
70 std::vector<std::string> tokens;
71 std::string token;
72 bool inQuotes = false;
73 for (size_t i = 0; i < str.length(); ++i) {
74 char c = str[i];
75 if (c == '"') {
76 inQuotes = !inQuotes;
77 } else if (std::isspace(c) && !inQuotes) {
78 if (!token.empty()) {
79 tokens.push_back(token);
80 token.clear();
81 }
82 } else {
83 token += c;
84 }
85 }
86 if (!token.empty()) {
87 tokens.push_back(token);
88 }
89 return tokens;
90 }
91
102 static bool validate_set(const std::vector<std::string> &tokens, ValidationResult &result) {
103 if (tokens.size() != 3) {
104 result.success = false;
105 result.errmsg = "wrong number of arguments for 'set' command";
106 return false;
107 }
108 if (tokens[1].empty()) {
109 result.success = false;
110 result.errmsg = "invalid key";
111 return false;
112 }
113 result.key = tokens[1];
114 result.value = tokens[2];
115 result.success = true;
116 return true;
117 }
118
129 static bool validate_get(const std::vector<std::string> &tokens, ValidationResult &result) {
130 if (tokens.size() != 2) {
131 result.success = false;
132 result.errmsg = "wrong number of arguments for 'get' command";
133 return false;
134 }
135 if (tokens[1].empty()) {
136 result.success = false;
137 result.errmsg = "invalid key";
138 return false;
139 }
140 result.key = tokens[1];
141 result.success = true;
142 return true;
143 }
144
155 static bool validate_del(const std::vector<std::string> &tokens, ValidationResult &result) {
156 if (tokens.size() != 2) {
157 result.success = false;
158 result.errmsg = "wrong number of arguments for 'del' command";
159 return false;
160 }
161 if (tokens[1].empty()) {
162 result.success = false;
163 result.errmsg = "invalid key";
164 return false;
165 }
166 result.key = tokens[1];
167 result.success = true;
168 return true;
169 }
178 std::string
179 help() {
180 return "Available commands:\n"
181 " SET <key> <value> - Set key to hold the string value\n"
182 " GET <key> - Get the value of key\n"
183 " DEL <key> - Delete a key\n"
184 " help - Show this help menu\n"
185 " exit - Exit the program\n"
186 " clear - Clear the screen\n";
187 }
188
189public:
197
203 CommandParser() = default;
204
214 std::string parser(const std::string &line) {
215 try {
216 std::vector<std::string> tokens = split(line);
217 if (tokens.empty()) {
218 return "";
219 }
220
221 ValidationResult result;
222 std::string command = tokens[0];
223 std::transform(command.begin(), command.end(), command.begin(), ::tolower);
224
225 if (command == "set") {
226 if (!validate_set(tokens, result)) {
227 return RespEncoder::error(result.errmsg);
228 }
229 db.put(result.key, result.value);
230 return RespEncoder::simpleString("OK");
231 } else if (command == "get") {
232 if (!validate_get(tokens, result)) {
233 return RespEncoder::error(result.errmsg);
234 }
235 std::pair<bool, std::string> found_value = db.get(result.key);
236 if (!found_value.first) {
237 return "NULL\n";
238 }
239 return found_value.second + "\n";
240 } else if (command == "del") {
241 if (!validate_del(tokens, result)) {
242 return RespEncoder::error(result.errmsg);
243 }
244 std::pair<bool, std::string> found_value = db.get(result.key);
245 if (!found_value.first) {
246 return "key \"" + result.key + "\" not found\n";
247 }
248 db.remove(result.key);
249 return RespEncoder::integer(1);
250 } else if (command == "help") {
251 return help();
252 } else if (command == "exit") {
253 exit(0);
254 } else if (command == "clear") {
255 return "\033[2J\033[1;1H";
256 } else {
257 return RespEncoder::error("unknown command '" + command + "'");
258 }
259 } catch (const std::exception &e) {
260 return RespEncoder::error(e.what());
261 }
262 return "";
263 }
264};
265
266#endif
LSMTree db
Database engine instance.
Definition command_parser.hpp:196
CommandParser()=default
Default constructor for CommandParser.
std::string parser(const std::string &line)
Parses and executes a command.
Definition command_parser.hpp:214
LSM Tree implementation.
Definition lsm.hpp:37
static std::string simpleString(const std::string &str)
Converts a simple string to RESP format.
Definition resp_encoder.hpp:30
static std::string error(const std::string &message)
Converts an error message to RESP format.
Definition resp_encoder.hpp:44
static std::string integer(int value)
Used to encode an integer to RESP format.
Definition resp_encoder.hpp:57
Holds the result of command validation.
Definition command_parser.hpp:27
bool success
Indicates whether the validation was successful.
Definition command_parser.hpp:32
ValidationResult()
Default constructor initializes the result to failure.
Definition command_parser.hpp:48
std::string errmsg
Error message if validation failed.
Definition command_parser.hpp:36
std::string key
Key associated with the command.
Definition command_parser.hpp:40
std::string value
Value associated with the command.
Definition command_parser.hpp:44
LSM Tree implementation.
Used to encode messages into RESP (REdis Serialization Protocol) format.