diff --git a/src/Error.cpp b/src/Error.cpp index 76c7740..e9b92b7 100644 --- a/src/Error.cpp +++ b/src/Error.cpp @@ -2,6 +2,7 @@ // Created by wolverindev on 17.10.17. // +#include "./query/command3.h" #include "Error.h" using namespace ts; @@ -207,4 +208,59 @@ ErrorType ts::findError(std::string key){ for(auto elm : avariableErrors) if(elm.name == key) return elm; return ErrorType{1, key, "undefined"}; +} + +inline void write_command_result_error(ts::command_builder_bulk bulk, const command_result& result, const std::string_view& id_key) { + bulk.put_unchecked(id_key, (uint32_t) result.error_code()); + bulk.put_unchecked("msg", findError(result.error_code()).message); + if(result.is_permission_error()) + bulk.put_unchecked("failed_permid", (uint32_t) result.permission_id()); +} + +inline void write_command_result_detailed(ts::command_builder_bulk bulk, const command_result& result, const std::string_view& id_key) { + auto details = result.details(); + bulk.put_unchecked(id_key, (uint32_t) details->error_id); + bulk.put_unchecked("msg", findError(details->error_id).message); + + for(const auto& extra : details->extra_properties) + bulk.put(extra.first, extra.second); +} + +void command_result::build_error_response(ts::command_builder &builder, const std::string_view &idKey) const { + switch(this->type()) { + case command_result_type::error: + write_command_result_error(builder.bulk(0), *this, idKey); + break; + case command_result_type::detailed: + write_command_result_detailed(builder.bulk(0), *this, idKey); + break; + + case command_result_type::bulked: { + auto bulks = this->bulks(); + builder.reserve_bulks(bulks->size()); + for(size_t index{0}; index < bulks->size(); index++) { + auto& entry = bulks->at(index); + switch (entry.type()) { + case command_result_type::error: + write_command_result_error(builder.bulk(index), entry, idKey); + break; + case command_result_type::detailed: + write_command_result_detailed(builder.bulk(index), entry, idKey); + break; + case command_result_type::bulked: + assert(false); + break; + } + } + if(bulks->empty()) { + assert(false); + builder.put_unchecked(0, idKey, (uint32_t) error::ok); + builder.put_unchecked(0, "msg", findError(error::ok).message); + } + break; + } + default: + assert(false); + break; + } } \ No newline at end of file diff --git a/src/Error.h b/src/Error.h index c98a7a2..806108b 100644 --- a/src/Error.h +++ b/src/Error.h @@ -275,17 +275,6 @@ namespace ts { return (detailed_command_result*) (this->data & MASK_PTR); } -#if 0 // Dont use release_details. Use release_data instead - [[nodiscard]] inline std::unique_ptr release_details() { - auto type = this->type(); - if(type != command_result_type::detailed) return nullptr; - - auto result = this->details(); - this->data = 0; - return std::unique_ptr{result}; - } -#endif - /* only valid for command_result_type::bulked */ [[nodiscard]] inline const std::vector* bulks() const { assert(this->type() == command_result_type::bulked); @@ -298,20 +287,9 @@ namespace ts { return (std::vector*) (this->data & MASK_PTR); } -#if 0 // Dont use release_bulks. Use release_data instead - [[nodiscard]] inline std::vector release_bulks() { - auto type = this->type(); - if(type != command_result_type::bulked) return {}; - - std::vector result{}; - auto bulks = reinterpret_cast*>(this->data); - result.swap(*bulks); - delete bulks; - this->data = 0; - return result; - } +#ifdef COMMAND_BUILDER_DEFINED + void build_error_response(ts::command_builder& /* result */, const std::string_view& /* id key */) const; #endif - inline command_result& reset(command_result&& other) { this->release_data(); std::exchange(this->data, other.data); diff --git a/src/query/command3.cpp b/src/query/command3.cpp index dba1b30..e249b15 100644 --- a/src/query/command3.cpp +++ b/src/query/command3.cpp @@ -10,14 +10,14 @@ using namespace ts; command_bulk command_parser::empty_bulk{std::string::npos, 0, ""}; bool command_parser::parse(bool command) { - this->data = this->_command; + this->data = this->_command_memory; this->index = std::string::npos; size_t index{0}, findex; if(command) { - index = this->_command.find(' ', index); + index = this->_command_memory.find(' ', index); if(index == std::string::npos) { - this->command_type = this->_command; + this->command_type = this->_command_memory; return true; } else { this->command_type = this->data.substr(0, index); @@ -27,10 +27,10 @@ bool command_parser::parse(bool command) { } this->_bulks.reserve(4); - while(index < this->_command.size()) { - findex = this->_command.find('|', index); + while(index < this->_command_memory.size()) { + findex = this->_command_memory.find('|', index); if(findex == std::string::npos) - findex = this->_command.size(); + findex = this->_command_memory.size(); this->_bulks.emplace_back(this->_bulks.size() - 1, index, this->data.substr(index, findex - index)); index = findex + 1; diff --git a/src/query/command3.h b/src/query/command3.h index cc092df..60dc6da 100644 --- a/src/query/command3.h +++ b/src/query/command3.h @@ -141,7 +141,8 @@ namespace ts { failed }; - explicit command_parser(std::string command) : impl::command_string_parser{std::string::npos, 0, command}, _command{std::move(command)} { } + explicit command_parser(std::string_view command) : impl::command_string_parser{std::string::npos, 0, command} { } + explicit command_parser(std::string command) : impl::command_string_parser{std::string::npos, 0, command}, _command_memory{std::move(command)} { } bool parse(bool /* contains identifier */); @@ -158,9 +159,27 @@ namespace ts { size_t index{0}; do { index = this->data.find(key, index); - index -= 1; - if(index > key.size()) return false; - if(this->data[index] == '-') return index == 0 || this->data[index - 1] == ' '; + index--; + + if(index > this->data.length()) + return false; /* index was zero or std::string::npos*/ + + if(this->data[index] != '-') { + index += 2; + continue; + } + + if(index != 0 && this->data[index - 1] != ' ') { + index += 2; + continue; + } + + if(index + 1 + key.length() >= this->data.length()) + return true; + + if(this->data[index + 1 + key.length()] == ' ') + return true; + index += 2; } while(true); } @@ -171,7 +190,7 @@ namespace ts { private: static command_bulk empty_bulk; - const std::string _command{}; + const std::string _command_memory{}; std::string_view command_type{}; std::vector _bulks{}; }; @@ -368,4 +387,6 @@ namespace ts { }; using command_builder = command_builder_impl<>; -} \ No newline at end of file +} + +#define COMMAND_BUILDER_DEFINED \ No newline at end of file