Fixed the permfind command
This commit is contained in:
parent
889477c646
commit
c879f3b776
@ -156,6 +156,66 @@ namespace ts {
|
|||||||
std::vector<std::string_view> flags{};
|
std::vector<std::string_view> flags{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class command_builder_bulk {
|
||||||
|
template <typename vector_t>
|
||||||
|
friend class command_builder_impl;
|
||||||
|
public:
|
||||||
|
inline void put(const std::string_view& key, const std::string_view& value) {
|
||||||
|
size_t begin, end;
|
||||||
|
if(impl::value_raw_impl(this->bulk, key, begin, &end)) {
|
||||||
|
std::string result{};
|
||||||
|
result.reserve(this->bulk.size());
|
||||||
|
|
||||||
|
result.append(this->bulk, 0, begin - key.size() - 1); /* key incl = */
|
||||||
|
result.append(this->bulk, end + 1); /* get rid of the space */
|
||||||
|
this->bulk = result;
|
||||||
|
}
|
||||||
|
this->impl_put_unchecked(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
|
||||||
|
inline void put(const std::string_view& key, const T& value) {
|
||||||
|
static_assert(converter<T>::supported, "Target type isn't supported!");
|
||||||
|
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
|
||||||
|
auto data = converter<T>::to_string(value);
|
||||||
|
this->put(key, std::string_view{data});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* directly puts data without checking for duplicates */
|
||||||
|
inline void put_unchecked(const std::string_view& key, const std::string_view& value) {
|
||||||
|
this->impl_put_unchecked(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void put_unchecked(const std::string_view& key, const std::string& value) {
|
||||||
|
this->put_unchecked(key, std::string_view{value});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
|
||||||
|
inline void put_unchecked(const std::string_view& key, const T& value) {
|
||||||
|
static_assert(converter<T>::supported, "Target type isn't supported!");
|
||||||
|
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
|
||||||
|
auto data = converter<T>::to_string(value);
|
||||||
|
this->put_unchecked(key, std::string_view{data});
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool& flag_changed;
|
||||||
|
std::string& bulk;
|
||||||
|
explicit command_builder_bulk(bool& change_flag, std::string& bulk) : flag_changed{change_flag}, bulk{bulk} {}
|
||||||
|
|
||||||
|
void impl_put_unchecked(const std::string_view& key, const std::string_view& value) {
|
||||||
|
auto escaped_value = ts::query::escape(std::string{value});
|
||||||
|
|
||||||
|
this->bulk.reserve(this->bulk.length() + key.size() + escaped_value.size() + 2);
|
||||||
|
this->bulk.append(key);
|
||||||
|
if(!escaped_value.empty()) {
|
||||||
|
this->bulk.append("=");
|
||||||
|
this->bulk.append(escaped_value);
|
||||||
|
}
|
||||||
|
this->bulk.append(" ");
|
||||||
|
this->flag_changed = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename vector_t = std::vector<std::string>>
|
template <typename vector_t = std::vector<std::string>>
|
||||||
class command_builder_impl {
|
class command_builder_impl {
|
||||||
public:
|
public:
|
||||||
@ -169,7 +229,7 @@ namespace ts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::string build(bool with_empty = false) const {
|
inline std::string build(bool with_empty = false) const {
|
||||||
if(this->builded.has_value())
|
if(this->builded.has_value() && !this->flag_changed)
|
||||||
return this->builded.value();
|
return this->builded.value();
|
||||||
|
|
||||||
std::string result{};
|
std::string result{};
|
||||||
@ -189,74 +249,35 @@ namespace ts {
|
|||||||
this->builded = result.substr(0, result.length() - 1);
|
this->builded = result.substr(0, result.length() - 1);
|
||||||
else
|
else
|
||||||
this->builded = result;
|
this->builded = result;
|
||||||
|
this->flag_changed = false;
|
||||||
return this->builded.value();
|
return this->builded.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void reserve_bulks(size_t count) { this->bulks.reserve(count); }
|
inline void reserve_bulks(size_t count) { this->bulks.reserve(count); }
|
||||||
|
|
||||||
inline void put(size_t index, const std::string_view& key, const std::string_view& value) {
|
[[nodiscard]] inline command_builder_bulk bulk(size_t index) {
|
||||||
while(this->bulks.size() <= index)
|
while(this->bulks.size() <= index)
|
||||||
this->bulks.emplace_back("").reserve(expected_bulk_size);
|
this->bulks.emplace_back("").reserve(expected_bulk_size);
|
||||||
|
|
||||||
auto& data = this->bulks[index];
|
return command_builder_bulk{this->flag_changed, this->bulks[index]};
|
||||||
size_t begin, end;
|
|
||||||
if(impl::value_raw_impl(data, key, begin, &end)) {
|
|
||||||
std::string result{};
|
|
||||||
result.reserve(data.size());
|
|
||||||
|
|
||||||
result.append(data, 0, begin - key.size() - 1); /* key incl = */
|
|
||||||
result.append(data, end + 1); /* get rid of the space */
|
|
||||||
data = result;
|
|
||||||
}
|
|
||||||
this->impl_put_unchecked(data, index, key, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
|
template <typename T>
|
||||||
inline void put(size_t index, const std::string_view& key, const T& value) {
|
inline void put(size_t index, const std::string_view& key, const T& value) {
|
||||||
static_assert(converter<T>::supported, "Target type isn't supported!");
|
this->bulk(index).put(key, value);
|
||||||
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
|
|
||||||
auto data = converter<T>::to_string(value);
|
|
||||||
this->put(index, key, std::string_view{data});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* directly puts data without checking for duplicates */
|
/* directly puts data without checking for duplicates */
|
||||||
inline void put_unchecked(size_t index, const std::string_view& key, const std::string_view& value) {
|
template <typename T>
|
||||||
while(this->bulks.size() <= index)
|
|
||||||
this->bulks.emplace_back("").reserve(expected_bulk_size);
|
|
||||||
|
|
||||||
this->impl_put_unchecked(this->bulks[index], index, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void put_unchecked(size_t index, const std::string_view& key, const std::string& value) {
|
|
||||||
this->put_unchecked(index, key, std::string_view{value});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, std::enable_if_t<!(std::is_same<T, std::string_view>::value || std::is_same<T, std::string>::value), int> = 1>
|
|
||||||
inline void put_unchecked(size_t index, const std::string_view& key, const T& value) {
|
inline void put_unchecked(size_t index, const std::string_view& key, const T& value) {
|
||||||
static_assert(converter<T>::supported, "Target type isn't supported!");
|
this->bulk(index).put_unchecked(key, value);
|
||||||
static_assert(!converter<T>::supported || converter<T>::to_string, "Target type dosn't support building");
|
|
||||||
auto data = converter<T>::to_string(value);
|
|
||||||
this->put_unchecked(index, key, std::string_view{data});
|
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
command_builder_impl(size_t expected, size_t identifier, typename vector_t::iterator begin, typename vector_t::iterator end) : expected_bulk_size{expected}, _identifier{identifier}, bulks{begin, end} {}
|
command_builder_impl(size_t expected, std::string identifier, typename vector_t::iterator begin, typename vector_t::iterator end) : expected_bulk_size{expected}, _identifier{std::move(identifier)}, bulks{begin, end} {}
|
||||||
|
|
||||||
void impl_put_unchecked(std::string& data, size_t index, const std::string_view& key, const std::string_view& value) {
|
|
||||||
auto escaped_value = ts::query::escape(std::string{value});
|
|
||||||
|
|
||||||
data.reserve(data.length() + key.size() + escaped_value.size() + 2);
|
|
||||||
data.append(key);
|
|
||||||
if(!escaped_value.empty()) {
|
|
||||||
data.append("=");
|
|
||||||
data.append(escaped_value);
|
|
||||||
}
|
|
||||||
data.append(" ");
|
|
||||||
|
|
||||||
this->builded.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t expected_bulk_size;
|
const size_t expected_bulk_size;
|
||||||
const std::string _identifier;
|
const std::string _identifier;
|
||||||
|
mutable bool flag_changed{false};
|
||||||
mutable std::optional<std::string> builded{};
|
mutable std::optional<std::string> builded{};
|
||||||
vector_t bulks{};
|
vector_t bulks{};
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user