PMR property value
This commit is contained in:
parent
5aeaad198b
commit
49ad114366
@ -238,7 +238,7 @@ Value ToBoltValue(const storage::PropertyValue &value) {
|
|||||||
case storage::PropertyValue::Type::Double:
|
case storage::PropertyValue::Type::Double:
|
||||||
return Value(value.ValueDouble());
|
return Value(value.ValueDouble());
|
||||||
case storage::PropertyValue::Type::String:
|
case storage::PropertyValue::Type::String:
|
||||||
return Value(value.ValueString());
|
return Value(std::string{value.ValueString()});
|
||||||
case storage::PropertyValue::Type::List: {
|
case storage::PropertyValue::Type::List: {
|
||||||
const auto &values = value.ValueList();
|
const auto &values = value.ValueList();
|
||||||
std::vector<Value> vec;
|
std::vector<Value> vec;
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
#include <jemalloc/jemalloc.h>
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
@ -44,6 +46,7 @@
|
|||||||
#include "query/procedure/py_module.hpp"
|
#include "query/procedure/py_module.hpp"
|
||||||
#include "requests/requests.hpp"
|
#include "requests/requests.hpp"
|
||||||
#include "storage/v2/isolation_level.hpp"
|
#include "storage/v2/isolation_level.hpp"
|
||||||
|
#include "storage/v2/property_value.hpp"
|
||||||
#include "storage/v2/storage.hpp"
|
#include "storage/v2/storage.hpp"
|
||||||
#include "storage/v2/view.hpp"
|
#include "storage/v2/view.hpp"
|
||||||
#include "telemetry/telemetry.hpp"
|
#include "telemetry/telemetry.hpp"
|
||||||
@ -817,7 +820,7 @@ class BoltSession final : public communication::bolt::Session<communication::Inp
|
|||||||
|
|
||||||
std::pair<std::vector<std::string>, std::optional<int>> Interpret(
|
std::pair<std::vector<std::string>, std::optional<int>> Interpret(
|
||||||
const std::string &query, const std::map<std::string, communication::bolt::Value> ¶ms) override {
|
const std::string &query, const std::map<std::string, communication::bolt::Value> ¶ms) override {
|
||||||
std::map<std::string, storage::PropertyValue> params_pv;
|
storage::PropertyValue::TMap params_pv{utils::NewDeleteResource()};
|
||||||
for (const auto &kv : params) params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second));
|
for (const auto &kv : params) params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second));
|
||||||
const std::string *username{nullptr};
|
const std::string *username{nullptr};
|
||||||
if (user_) {
|
if (user_) {
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
#include "query/cypher_query_interpreter.hpp"
|
#include "query/cypher_query_interpreter.hpp"
|
||||||
|
|
||||||
|
#include "utils/memory.hpp"
|
||||||
|
#include "utils/pmr/string.hpp"
|
||||||
|
|
||||||
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
DEFINE_HIDDEN_bool(query_cost_planner, true, "Use the cost-estimating query planner.");
|
DEFINE_HIDDEN_bool(query_cost_planner, true, "Use the cost-estimating query planner.");
|
||||||
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
||||||
@ -20,7 +23,7 @@ DEFINE_VALIDATED_int32(query_plan_cache_ttl, 60, "Time to live for cached query
|
|||||||
namespace query {
|
namespace query {
|
||||||
CachedPlan::CachedPlan(std::unique_ptr<LogicalPlan> plan) : plan_(std::move(plan)) {}
|
CachedPlan::CachedPlan(std::unique_ptr<LogicalPlan> plan) : plan_(std::move(plan)) {}
|
||||||
|
|
||||||
ParsedQuery ParseQuery(const std::string &query_string, const std::map<std::string, storage::PropertyValue> ¶ms,
|
ParsedQuery ParseQuery(const std::string &query_string, const storage::PropertyValue::TMap ¶ms,
|
||||||
utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
|
utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
|
||||||
const InterpreterConfig::Query &query_config) {
|
const InterpreterConfig::Query &query_config) {
|
||||||
// Strip the query for caching purposes. The process of stripping a query
|
// Strip the query for caching purposes. The process of stripping a query
|
||||||
@ -34,7 +37,7 @@ ParsedQuery ParseQuery(const std::string &query_string, const std::map<std::stri
|
|||||||
|
|
||||||
// Check that all user-specified parameters are provided.
|
// Check that all user-specified parameters are provided.
|
||||||
for (const auto ¶m_pair : stripped_query.parameters()) {
|
for (const auto ¶m_pair : stripped_query.parameters()) {
|
||||||
auto it = params.find(param_pair.second);
|
auto it = params.find(utils::pmr::string{param_pair.second, utils::NewDeleteResource()});
|
||||||
|
|
||||||
if (it == params.end()) {
|
if (it == params.end()) {
|
||||||
throw query::UnprovidedParameterError("Parameter ${} not provided.", param_pair.second);
|
throw query::UnprovidedParameterError("Parameter ${} not provided.", param_pair.second);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "query/frontend/semantic/symbol_generator.hpp"
|
#include "query/frontend/semantic/symbol_generator.hpp"
|
||||||
#include "query/frontend/stripped.hpp"
|
#include "query/frontend/stripped.hpp"
|
||||||
#include "query/plan/planner.hpp"
|
#include "query/plan/planner.hpp"
|
||||||
|
#include "storage/v2/property_value.hpp"
|
||||||
#include "utils/flag_validation.hpp"
|
#include "utils/flag_validation.hpp"
|
||||||
#include "utils/timer.hpp"
|
#include "utils/timer.hpp"
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ struct PlanCacheEntry {
|
|||||||
*/
|
*/
|
||||||
struct ParsedQuery {
|
struct ParsedQuery {
|
||||||
std::string query_string;
|
std::string query_string;
|
||||||
std::map<std::string, storage::PropertyValue> user_parameters;
|
storage::PropertyValue::TMap user_parameters;
|
||||||
Parameters parameters;
|
Parameters parameters;
|
||||||
frontend::StrippedQuery stripped_query;
|
frontend::StrippedQuery stripped_query;
|
||||||
AstStorage ast_storage;
|
AstStorage ast_storage;
|
||||||
@ -110,7 +111,7 @@ struct ParsedQuery {
|
|||||||
bool is_cacheable{true};
|
bool is_cacheable{true};
|
||||||
};
|
};
|
||||||
|
|
||||||
ParsedQuery ParseQuery(const std::string &query_string, const std::map<std::string, storage::PropertyValue> ¶ms,
|
ParsedQuery ParseQuery(const std::string &query_string, const storage::PropertyValue::TMap ¶ms,
|
||||||
utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
|
utils::SkipList<QueryCacheEntry> *cache, utils::SpinLock *antlr_lock,
|
||||||
const InterpreterConfig::Query &query_config);
|
const InterpreterConfig::Query &query_config);
|
||||||
|
|
||||||
|
@ -83,6 +83,7 @@ template <typename T>
|
|||||||
void PrintObject(std::ostream *out, const T &arg);
|
void PrintObject(std::ostream *out, const T &arg);
|
||||||
|
|
||||||
void PrintObject(std::ostream *out, const std::string &str);
|
void PrintObject(std::ostream *out, const std::string &str);
|
||||||
|
void PrintObject(std::ostream *out, const utils::pmr::string &str);
|
||||||
|
|
||||||
void PrintObject(std::ostream *out, Aggregation::Op op);
|
void PrintObject(std::ostream *out, Aggregation::Op op);
|
||||||
|
|
||||||
@ -95,9 +96,15 @@ void PrintObject(std::ostream *out, const storage::PropertyValue &value);
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void PrintObject(std::ostream *out, const std::vector<T> &vec);
|
void PrintObject(std::ostream *out, const std::vector<T> &vec);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void PrintObject(std::ostream *out, const utils::pmr::vector<T> &vec);
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V>
|
||||||
void PrintObject(std::ostream *out, const std::map<K, V> &map);
|
void PrintObject(std::ostream *out, const std::map<K, V> &map);
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void PrintObject(std::ostream *out, const utils::pmr::map<K, V> &map);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PrintObject(std::ostream *out, const T &arg) {
|
void PrintObject(std::ostream *out, const T &arg) {
|
||||||
static_assert(!std::is_convertible<T, Expression *>::value,
|
static_assert(!std::is_convertible<T, Expression *>::value,
|
||||||
@ -109,6 +116,7 @@ void PrintObject(std::ostream *out, const T &arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PrintObject(std::ostream *out, const std::string &str) { *out << utils::Escape(str); }
|
void PrintObject(std::ostream *out, const std::string &str) { *out << utils::Escape(str); }
|
||||||
|
void PrintObject(std::ostream *out, const utils::pmr::string &str) { *out << utils::Escape(str); }
|
||||||
|
|
||||||
void PrintObject(std::ostream *out, Aggregation::Op op) { *out << Aggregation::OpToString(op); }
|
void PrintObject(std::ostream *out, Aggregation::Op op) { *out << Aggregation::OpToString(op); }
|
||||||
|
|
||||||
@ -165,6 +173,13 @@ void PrintObject(std::ostream *out, const std::vector<T> &vec) {
|
|||||||
*out << "]";
|
*out << "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void PrintObject(std::ostream *out, const utils::pmr::vector<T> &vec) {
|
||||||
|
*out << "[";
|
||||||
|
utils::PrintIterable(*out, vec, ", ", [](auto &stream, const auto &item) { PrintObject(&stream, item); });
|
||||||
|
*out << "]";
|
||||||
|
}
|
||||||
|
|
||||||
template <typename K, typename V>
|
template <typename K, typename V>
|
||||||
void PrintObject(std::ostream *out, const std::map<K, V> &map) {
|
void PrintObject(std::ostream *out, const std::map<K, V> &map) {
|
||||||
*out << "{";
|
*out << "{";
|
||||||
@ -176,6 +191,17 @@ void PrintObject(std::ostream *out, const std::map<K, V> &map) {
|
|||||||
*out << "}";
|
*out << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
void PrintObject(std::ostream *out, const utils::pmr::map<K, V> &map) {
|
||||||
|
*out << "{";
|
||||||
|
utils::PrintIterable(*out, map, ", ", [](auto &stream, const auto &item) {
|
||||||
|
PrintObject(&stream, item.first);
|
||||||
|
stream << ": ";
|
||||||
|
PrintObject(&stream, item.second);
|
||||||
|
});
|
||||||
|
*out << "}";
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PrintOperatorArgs(std::ostream *out, const T &arg) {
|
void PrintOperatorArgs(std::ostream *out, const T &arg) {
|
||||||
*out << " ";
|
*out << " ";
|
||||||
|
@ -1503,8 +1503,7 @@ TriggerEventType ToTriggerEventType(const TriggerQuery::EventType event_type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Callback CreateTrigger(TriggerQuery *trigger_query,
|
Callback CreateTrigger(TriggerQuery *trigger_query, const storage::PropertyValue::TMap &user_parameters,
|
||||||
const std::map<std::string, storage::PropertyValue> &user_parameters,
|
|
||||||
InterpreterContext *interpreter_context, DbAccessor *dba, std::optional<std::string> owner) {
|
InterpreterContext *interpreter_context, DbAccessor *dba, std::optional<std::string> owner) {
|
||||||
return {
|
return {
|
||||||
{},
|
{},
|
||||||
@ -1554,7 +1553,7 @@ Callback ShowTriggers(InterpreterContext *interpreter_context) {
|
|||||||
|
|
||||||
PreparedQuery PrepareTriggerQuery(ParsedQuery parsed_query, const bool in_explicit_transaction,
|
PreparedQuery PrepareTriggerQuery(ParsedQuery parsed_query, const bool in_explicit_transaction,
|
||||||
std::vector<Notification> *notifications, InterpreterContext *interpreter_context,
|
std::vector<Notification> *notifications, InterpreterContext *interpreter_context,
|
||||||
DbAccessor *dba, const std::map<std::string, storage::PropertyValue> &user_parameters,
|
DbAccessor *dba, const storage::PropertyValue::TMap &user_parameters,
|
||||||
const std::string *username) {
|
const std::string *username) {
|
||||||
if (in_explicit_transaction) {
|
if (in_explicit_transaction) {
|
||||||
throw TriggerModificationInMulticommandTxException();
|
throw TriggerModificationInMulticommandTxException();
|
||||||
@ -1604,8 +1603,7 @@ PreparedQuery PrepareTriggerQuery(ParsedQuery parsed_query, const bool in_explic
|
|||||||
|
|
||||||
PreparedQuery PrepareStreamQuery(ParsedQuery parsed_query, const bool in_explicit_transaction,
|
PreparedQuery PrepareStreamQuery(ParsedQuery parsed_query, const bool in_explicit_transaction,
|
||||||
std::vector<Notification> *notifications, InterpreterContext *interpreter_context,
|
std::vector<Notification> *notifications, InterpreterContext *interpreter_context,
|
||||||
DbAccessor *dba,
|
DbAccessor *dba, const storage::PropertyValue::TMap & /*user_parameters*/,
|
||||||
const std::map<std::string, storage::PropertyValue> & /*user_parameters*/,
|
|
||||||
const std::string *username) {
|
const std::string *username) {
|
||||||
if (in_explicit_transaction) {
|
if (in_explicit_transaction) {
|
||||||
throw StreamQueryInMulticommandTxException();
|
throw StreamQueryInMulticommandTxException();
|
||||||
@ -2033,7 +2031,7 @@ void Interpreter::RollbackTransaction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
|
Interpreter::PrepareResult Interpreter::Prepare(const std::string &query_string,
|
||||||
const std::map<std::string, storage::PropertyValue> ¶ms,
|
const storage::PropertyValue::TMap ¶ms,
|
||||||
const std::string *username) {
|
const std::string *username) {
|
||||||
if (!in_explicit_transaction_) {
|
if (!in_explicit_transaction_) {
|
||||||
query_executions_.clear();
|
query_executions_.clear();
|
||||||
|
@ -220,7 +220,7 @@ class Interpreter final {
|
|||||||
*
|
*
|
||||||
* @throw query::QueryException
|
* @throw query::QueryException
|
||||||
*/
|
*/
|
||||||
PrepareResult Prepare(const std::string &query, const std::map<std::string, storage::PropertyValue> ¶ms,
|
PrepareResult Prepare(const std::string &query, const storage::PropertyValue::TMap ¶ms,
|
||||||
const std::string *username);
|
const std::string *username);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1520,7 +1520,7 @@ storage::PropertyValue ToPropertyValue(const mgp_map &map) {
|
|||||||
storage::PropertyValue result{std::map<std::string, storage::PropertyValue>{}};
|
storage::PropertyValue result{std::map<std::string, storage::PropertyValue>{}};
|
||||||
auto &result_map = result.ValueMap();
|
auto &result_map = result.ValueMap();
|
||||||
for (const auto &[key, value] : map.items) {
|
for (const auto &[key, value] : map.items) {
|
||||||
result_map.insert_or_assign(std::string{key}, ToPropertyValue(value));
|
result_map.insert_or_assign(utils::pmr::string{key}, ToPropertyValue(value));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "query/serialization/property_value.hpp"
|
#include "query/serialization/property_value.hpp"
|
||||||
#include "storage/v2/property_value.hpp"
|
#include "storage/v2/property_value.hpp"
|
||||||
#include "utils/logging.hpp"
|
#include "utils/logging.hpp"
|
||||||
|
#include "utils/memory.hpp"
|
||||||
|
|
||||||
namespace query::serialization {
|
namespace query::serialization {
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ nlohmann::json SerializePropertyValue(const storage::PropertyValue &property_val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json SerializePropertyValueVector(const std::vector<storage::PropertyValue> &values) {
|
nlohmann::json SerializePropertyValueVector(const storage::PropertyValue::TVector &values) {
|
||||||
nlohmann::json array = nlohmann::json::array();
|
nlohmann::json array = nlohmann::json::array();
|
||||||
for (const auto &value : values) {
|
for (const auto &value : values) {
|
||||||
array.push_back(SerializePropertyValue(value));
|
array.push_back(SerializePropertyValue(value));
|
||||||
@ -54,6 +55,18 @@ nlohmann::json SerializePropertyValueVector(const std::vector<storage::PropertyV
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlohmann::json SerializePropertyValueMap(const storage::PropertyValue::TMap ¶meters) {
|
||||||
|
nlohmann::json data = nlohmann::json::object();
|
||||||
|
data.emplace("type", static_cast<uint64_t>(ObjectType::MAP));
|
||||||
|
data.emplace("value", nlohmann::json::object());
|
||||||
|
|
||||||
|
for (const auto &[key, value] : parameters) {
|
||||||
|
data["value"][std::string{key}] = SerializePropertyValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
nlohmann::json SerializePropertyValueMap(const std::map<std::string, storage::PropertyValue> ¶meters) {
|
nlohmann::json SerializePropertyValueMap(const std::map<std::string, storage::PropertyValue> ¶meters) {
|
||||||
nlohmann::json data = nlohmann::json::object();
|
nlohmann::json data = nlohmann::json::object();
|
||||||
data.emplace("type", static_cast<uint64_t>(ObjectType::MAP));
|
data.emplace("type", static_cast<uint64_t>(ObjectType::MAP));
|
||||||
@ -112,9 +125,9 @@ std::vector<storage::PropertyValue> DeserializePropertyValueList(const nlohmann:
|
|||||||
return property_values;
|
return property_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, storage::PropertyValue> DeserializePropertyValueMap(const nlohmann::json::object_t &data) {
|
storage::PropertyValue::TMap DeserializePropertyValueMap(const nlohmann::json::object_t &data) {
|
||||||
MG_ASSERT(data.at("type").get<ObjectType>() == ObjectType::MAP, "Invalid map serialization");
|
MG_ASSERT(data.at("type").get<ObjectType>() == ObjectType::MAP, "Invalid map serialization");
|
||||||
std::map<std::string, storage::PropertyValue> property_values;
|
storage::PropertyValue::TMap property_values{utils::NewDeleteResource()};
|
||||||
|
|
||||||
const nlohmann::json::object_t &values = data.at("value");
|
const nlohmann::json::object_t &values = data.at("value");
|
||||||
for (const auto &[key, value] : values) {
|
for (const auto &[key, value] : values) {
|
||||||
|
@ -19,7 +19,9 @@ namespace query::serialization {
|
|||||||
|
|
||||||
nlohmann::json SerializePropertyValue(const storage::PropertyValue &property_value);
|
nlohmann::json SerializePropertyValue(const storage::PropertyValue &property_value);
|
||||||
|
|
||||||
nlohmann::json SerializePropertyValueVector(const std::vector<storage::PropertyValue> &values);
|
nlohmann::json SerializePropertyValueVector(const storage::PropertyValue::TVector &values);
|
||||||
|
|
||||||
|
nlohmann::json SerializePropertyValueMap(const storage::PropertyValue::TMap ¶meters);
|
||||||
|
|
||||||
nlohmann::json SerializePropertyValueMap(const std::map<std::string, storage::PropertyValue> ¶meters);
|
nlohmann::json SerializePropertyValueMap(const std::map<std::string, storage::PropertyValue> ¶meters);
|
||||||
|
|
||||||
@ -27,6 +29,6 @@ storage::PropertyValue DeserializePropertyValue(const nlohmann::json &data);
|
|||||||
|
|
||||||
std::vector<storage::PropertyValue> DeserializePropertyValueList(const nlohmann::json::array_t &data);
|
std::vector<storage::PropertyValue> DeserializePropertyValueList(const nlohmann::json::array_t &data);
|
||||||
|
|
||||||
std::map<std::string, storage::PropertyValue> DeserializePropertyValueMap(const nlohmann::json::object_t &data);
|
storage::PropertyValue::TMap DeserializePropertyValueMap(const nlohmann::json::object_t &data);
|
||||||
|
|
||||||
} // namespace query::serialization
|
} // namespace query::serialization
|
||||||
|
@ -523,7 +523,7 @@ Streams::StreamsMap::iterator Streams::CreateConsumer(StreamsMap &map, const std
|
|||||||
interpreter->Abort();
|
interpreter->Abort();
|
||||||
}};
|
}};
|
||||||
|
|
||||||
const static std::map<std::string, storage::PropertyValue> empty_parameters{};
|
const static storage::PropertyValue::TMap empty_parameters{utils::NewDeleteResource()};
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
|
@ -150,8 +150,7 @@ std::vector<std::pair<Identifier, TriggerIdentifierTag>> GetPredefinedIdentifier
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Trigger::Trigger(std::string name, const std::string &query,
|
Trigger::Trigger(std::string name, const std::string &query, const storage::PropertyValue::TMap &user_parameters,
|
||||||
const std::map<std::string, storage::PropertyValue> &user_parameters,
|
|
||||||
const TriggerEventType event_type, utils::SkipList<QueryCacheEntry> *query_cache,
|
const TriggerEventType event_type, utils::SkipList<QueryCacheEntry> *query_cache,
|
||||||
DbAccessor *db_accessor, utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
DbAccessor *db_accessor, utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||||
std::optional<std::string> owner, const query::AuthChecker *auth_checker)
|
std::optional<std::string> owner, const query::AuthChecker *auth_checker)
|
||||||
@ -333,11 +332,11 @@ void TriggerStore::RestoreTriggers(utils::SkipList<QueryCacheEntry> *query_cache
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TriggerStore::AddTrigger(std::string name, const std::string &query,
|
void TriggerStore::AddTrigger(std::string name, const std::string &query,
|
||||||
const std::map<std::string, storage::PropertyValue> &user_parameters,
|
const storage::PropertyValue::TMap &user_parameters, TriggerEventType event_type,
|
||||||
TriggerEventType event_type, TriggerPhase phase,
|
TriggerPhase phase, utils::SkipList<QueryCacheEntry> *query_cache,
|
||||||
utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
|
DbAccessor *db_accessor, utils::SpinLock *antlr_lock,
|
||||||
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
const InterpreterConfig::Query &query_config, std::optional<std::string> owner,
|
||||||
std::optional<std::string> owner, const query::AuthChecker *auth_checker) {
|
const query::AuthChecker *auth_checker) {
|
||||||
std::unique_lock store_guard{store_lock_};
|
std::unique_lock store_guard{store_lock_};
|
||||||
if (storage_.Get(name)) {
|
if (storage_.Get(name)) {
|
||||||
throw utils::BasicException("Trigger with the same name already exists.");
|
throw utils::BasicException("Trigger with the same name already exists.");
|
||||||
|
@ -32,11 +32,10 @@
|
|||||||
|
|
||||||
namespace query {
|
namespace query {
|
||||||
struct Trigger {
|
struct Trigger {
|
||||||
explicit Trigger(std::string name, const std::string &query,
|
explicit Trigger(std::string name, const std::string &query, const storage::PropertyValue::TMap &user_parameters,
|
||||||
const std::map<std::string, storage::PropertyValue> &user_parameters, TriggerEventType event_type,
|
TriggerEventType event_type, utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
|
||||||
utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor, utils::SpinLock *antlr_lock,
|
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||||
const InterpreterConfig::Query &query_config, std::optional<std::string> owner,
|
std::optional<std::string> owner, const query::AuthChecker *auth_checker);
|
||||||
const query::AuthChecker *auth_checker);
|
|
||||||
|
|
||||||
void Execute(DbAccessor *dba, utils::MonotonicBufferResource *execution_memory, double max_execution_time_sec,
|
void Execute(DbAccessor *dba, utils::MonotonicBufferResource *execution_memory, double max_execution_time_sec,
|
||||||
std::atomic<bool> *is_shutting_down, const TriggerContext &context,
|
std::atomic<bool> *is_shutting_down, const TriggerContext &context,
|
||||||
@ -84,10 +83,9 @@ struct TriggerStore {
|
|||||||
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||||
const query::AuthChecker *auth_checker);
|
const query::AuthChecker *auth_checker);
|
||||||
|
|
||||||
void AddTrigger(std::string name, const std::string &query,
|
void AddTrigger(std::string name, const std::string &query, const storage::PropertyValue::TMap &user_parameters,
|
||||||
const std::map<std::string, storage::PropertyValue> &user_parameters, TriggerEventType event_type,
|
TriggerEventType event_type, TriggerPhase phase, utils::SkipList<QueryCacheEntry> *query_cache,
|
||||||
TriggerPhase phase, utils::SkipList<QueryCacheEntry> *query_cache, DbAccessor *db_accessor,
|
DbAccessor *db_accessor, utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
||||||
utils::SpinLock *antlr_lock, const InterpreterConfig::Query &query_config,
|
|
||||||
std::optional<std::string> owner, const query::AuthChecker *auth_checker);
|
std::optional<std::string> owner, const query::AuthChecker *auth_checker);
|
||||||
|
|
||||||
void DropTrigger(const std::string &name);
|
void DropTrigger(const std::string &name);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "storage/v2/property_value.hpp"
|
||||||
#include "storage/v2/temporal.hpp"
|
#include "storage/v2/temporal.hpp"
|
||||||
#include "utils/exceptions.hpp"
|
#include "utils/exceptions.hpp"
|
||||||
#include "utils/fnv.hpp"
|
#include "utils/fnv.hpp"
|
||||||
@ -278,12 +279,18 @@ TypedValue::operator storage::PropertyValue() const {
|
|||||||
case TypedValue::Type::Double:
|
case TypedValue::Type::Double:
|
||||||
return storage::PropertyValue(double_v);
|
return storage::PropertyValue(double_v);
|
||||||
case TypedValue::Type::String:
|
case TypedValue::Type::String:
|
||||||
return storage::PropertyValue(std::string(string_v));
|
return storage::PropertyValue(string_v, memory_);
|
||||||
case TypedValue::Type::List:
|
case TypedValue::Type::List: {
|
||||||
return storage::PropertyValue(std::vector<storage::PropertyValue>(list_v.begin(), list_v.end()));
|
storage::PropertyValue::TVector list{memory_};
|
||||||
|
list.reserve(list_v.size());
|
||||||
|
for (const auto &tv : list_v) {
|
||||||
|
list.emplace_back(storage::PropertyValue(tv));
|
||||||
|
}
|
||||||
|
return storage::PropertyValue(std::move(list));
|
||||||
|
}
|
||||||
case TypedValue::Type::Map: {
|
case TypedValue::Type::Map: {
|
||||||
std::map<std::string, storage::PropertyValue> map;
|
storage::PropertyValue::TMap map{memory_};
|
||||||
for (const auto &kv : map_v) map.emplace(kv.first, kv.second);
|
for (const auto &kv : map_v) map.emplace(kv.first, storage::PropertyValue(kv.second));
|
||||||
return storage::PropertyValue(std::move(map));
|
return storage::PropertyValue(std::move(map));
|
||||||
}
|
}
|
||||||
case Type::Date:
|
case Type::Date:
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
#include "storage/v2/temporal.hpp"
|
#include "storage/v2/temporal.hpp"
|
||||||
#include "utils/algorithm.hpp"
|
#include "utils/algorithm.hpp"
|
||||||
#include "utils/exceptions.hpp"
|
#include "utils/exceptions.hpp"
|
||||||
|
#include "utils/memory.hpp"
|
||||||
|
#include "utils/pmr/map.hpp"
|
||||||
|
#include "utils/pmr/string.hpp"
|
||||||
|
#include "utils/pmr/vector.hpp"
|
||||||
|
|
||||||
namespace storage {
|
namespace storage {
|
||||||
|
|
||||||
@ -48,6 +52,12 @@ class PropertyValue {
|
|||||||
TemporalData = 7
|
TemporalData = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using TString = utils::pmr::string;
|
||||||
|
using TVector = utils::pmr::vector<PropertyValue>;
|
||||||
|
using TMap = utils::pmr::map<utils::pmr::string, PropertyValue>;
|
||||||
|
|
||||||
|
using allocator_type = utils::Allocator<PropertyValue>;
|
||||||
|
|
||||||
static bool AreComparableTypes(Type a, Type b) {
|
static bool AreComparableTypes(Type a, Type b) {
|
||||||
return (a == b) || (a == Type::Int && b == Type::Double) || (a == Type::Double && b == Type::Int);
|
return (a == b) || (a == Type::Int && b == Type::Double) || (a == Type::Double && b == Type::Int);
|
||||||
}
|
}
|
||||||
@ -56,45 +66,204 @@ class PropertyValue {
|
|||||||
PropertyValue() : type_(Type::Null) {}
|
PropertyValue() : type_(Type::Null) {}
|
||||||
|
|
||||||
// constructors for primitive types
|
// constructors for primitive types
|
||||||
explicit PropertyValue(const bool value) : type_(Type::Bool) { bool_v = value; }
|
explicit PropertyValue(const bool value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
explicit PropertyValue(const int value) : type_(Type::Int) { int_v = value; }
|
: type_(Type::Bool), memory_{memory} {
|
||||||
explicit PropertyValue(const int64_t value) : type_(Type::Int) { int_v = value; }
|
bool_v = value;
|
||||||
explicit PropertyValue(const double value) : type_(Type::Double) { double_v = value; }
|
}
|
||||||
explicit PropertyValue(const TemporalData value) : type_{Type::TemporalData} { temporal_data_v = value; }
|
explicit PropertyValue(const int value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
|
: type_(Type::Int), memory_{memory} {
|
||||||
|
int_v = value;
|
||||||
|
}
|
||||||
|
explicit PropertyValue(const int64_t value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
|
: type_(Type::Int), memory_{memory} {
|
||||||
|
int_v = value;
|
||||||
|
}
|
||||||
|
explicit PropertyValue(const double value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
|
: type_(Type::Double), memory_{memory} {
|
||||||
|
double_v = value;
|
||||||
|
}
|
||||||
|
explicit PropertyValue(const TemporalData value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
|
: type_{Type::TemporalData}, memory_{memory} {
|
||||||
|
temporal_data_v = value;
|
||||||
|
}
|
||||||
|
|
||||||
// copy constructors for non-primitive types
|
// copy constructors for non-primitive types
|
||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
explicit PropertyValue(const std::string &value) : type_(Type::String) { new (&string_v) std::string(value); }
|
explicit PropertyValue(const std::string &value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
|
: type_(Type::String), memory_{memory} {
|
||||||
|
new (&string_v) TString(value, memory);
|
||||||
|
}
|
||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
/// @throw std::length_error if length of value exceeds
|
/// @throw std::length_error if length of value exceeds
|
||||||
/// std::string::max_length().
|
/// std::string::max_length().
|
||||||
explicit PropertyValue(const char *value) : type_(Type::String) { new (&string_v) std::string(value); }
|
explicit PropertyValue(const char *value, utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
/// @throw std::bad_alloc
|
: type_(Type::String), memory_{memory} {
|
||||||
explicit PropertyValue(const std::vector<PropertyValue> &value) : type_(Type::List) {
|
new (&string_v) TString(value, memory);
|
||||||
new (&list_v) std::vector<PropertyValue>(value);
|
|
||||||
}
|
|
||||||
/// @throw std::bad_alloc
|
|
||||||
explicit PropertyValue(const std::map<std::string, PropertyValue> &value) : type_(Type::Map) {
|
|
||||||
new (&map_v) std::map<std::string, PropertyValue>(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move constructors for non-primitive types
|
/**
|
||||||
explicit PropertyValue(std::string &&value) noexcept : type_(Type::String) {
|
* Construct a copy of other.
|
||||||
new (&string_v) std::string(std::move(value));
|
* utils::MemoryResource is obtained by calling
|
||||||
|
* std::allocator_traits<>::
|
||||||
|
* select_on_container_copy_construction(other.get_allocator()).
|
||||||
|
* Since we use utils::Allocator, which does not propagate, this means that
|
||||||
|
* memory_ will be the default utils::NewDeleteResource().
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(const TString &other)
|
||||||
|
: PropertyValue(other,
|
||||||
|
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(
|
||||||
|
other.get_allocator())
|
||||||
|
.GetMemoryResource()) {}
|
||||||
|
|
||||||
|
/** Construct a copy using the given utils::MemoryResource */
|
||||||
|
PropertyValue(const TString &other, utils::MemoryResource *memory) : type_(Type::String), memory_{memory} {
|
||||||
|
new (&string_v) TString(other, memory_);
|
||||||
}
|
}
|
||||||
explicit PropertyValue(std::vector<PropertyValue> &&value) noexcept : type_(Type::List) {
|
|
||||||
new (&list_v) std::vector<PropertyValue>(std::move(value));
|
/** Construct a copy using the given utils::MemoryResource */
|
||||||
|
explicit PropertyValue(const std::vector<PropertyValue> &value,
|
||||||
|
utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
|
: type_(Type::List), memory_(memory) {
|
||||||
|
new (&list_v) TVector(memory_);
|
||||||
|
list_v.reserve(value.size());
|
||||||
|
list_v.assign(value.begin(), value.end());
|
||||||
}
|
}
|
||||||
explicit PropertyValue(std::map<std::string, PropertyValue> &&value) noexcept : type_(Type::Map) {
|
|
||||||
new (&map_v) std::map<std::string, PropertyValue>(std::move(value));
|
/**
|
||||||
|
* Construct a copy of other.
|
||||||
|
* utils::MemoryResource is obtained by calling
|
||||||
|
* std::allocator_traits<>::
|
||||||
|
* select_on_container_copy_construction(other.get_allocator()).
|
||||||
|
* Since we use utils::Allocator, which does not propagate, this means that
|
||||||
|
* memory_ will be the default utils::NewDeleteResource().
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(const TVector &other)
|
||||||
|
: PropertyValue(other,
|
||||||
|
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(
|
||||||
|
other.get_allocator())
|
||||||
|
.GetMemoryResource()) {}
|
||||||
|
|
||||||
|
/** Construct a copy using the given utils::MemoryResource */
|
||||||
|
PropertyValue(const TVector &value, utils::MemoryResource *memory) : type_(Type::List), memory_(memory) {
|
||||||
|
new (&list_v) TVector(value, memory_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Construct a copy using the given utils::MemoryResource */
|
||||||
|
explicit PropertyValue(const std::map<std::string, PropertyValue> &value,
|
||||||
|
utils::MemoryResource *memory = utils::NewDeleteResource())
|
||||||
|
: type_(Type::Map), memory_{memory} {
|
||||||
|
new (&map_v) TMap(memory_);
|
||||||
|
for (const auto &kv : value) map_v.emplace(kv.first, kv.second);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Construct a copy of other.
|
||||||
|
* utils::MemoryResource is obtained by calling
|
||||||
|
* std::allocator_traits<>::
|
||||||
|
* select_on_container_copy_construction(other.get_allocator()).
|
||||||
|
* Since we use utils::Allocator, which does not propagate, this means that
|
||||||
|
* memory_ will be the default utils::NewDeleteResource().
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(const TMap &other)
|
||||||
|
: PropertyValue(other,
|
||||||
|
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(
|
||||||
|
other.get_allocator())
|
||||||
|
.GetMemoryResource()) {}
|
||||||
|
|
||||||
|
/** Construct a copy using the given utils::MemoryResource */
|
||||||
|
PropertyValue(const TMap &value, utils::MemoryResource *memory) : type_(Type::Map), memory_{memory} {
|
||||||
|
new (&map_v) TMap(value, memory_);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Construct with the value of other.
|
||||||
|
* utils::MemoryResource is obtained from other. After the move, other will be
|
||||||
|
* left in unspecified state.
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(TString &&other) noexcept
|
||||||
|
: PropertyValue(std::move(other), other.get_allocator().GetMemoryResource()) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct with the value of other and use the given MemoryResource
|
||||||
|
* After the move, other will be left in unspecified state.
|
||||||
|
*/
|
||||||
|
PropertyValue(TString &&other, utils::MemoryResource *memory) : type_(Type::String), memory_{memory} {
|
||||||
|
new (&string_v) TString(std::move(other), memory_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an element-wise move using default utils::NewDeleteResource().
|
||||||
|
* Other will be not be empty, though elements may be Null.
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(std::vector<PropertyValue> &&other)
|
||||||
|
: PropertyValue(std::move(other), utils::NewDeleteResource()) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an element-wise move of the other and use the given MemoryResource.
|
||||||
|
* Other will be not be left empty, though elements may be Null.
|
||||||
|
*/
|
||||||
|
PropertyValue(std::vector<PropertyValue> &&other, utils::MemoryResource *memory)
|
||||||
|
: type_(Type::List), memory_{memory} {
|
||||||
|
new (&list_v) TVector(memory_);
|
||||||
|
list_v.reserve(other.size());
|
||||||
|
// std::vector<PropertyValue> has std::allocator and there's no move
|
||||||
|
// constructor for std::vector using different allocator types. Since
|
||||||
|
// std::allocator is not propagated to elements, it is possible that some
|
||||||
|
// PropertyValue elements have a MemoryResource that is the same as the one we
|
||||||
|
// are given. In such a case we would like to move those PropertyValue
|
||||||
|
// instances, so we use move_iterator.
|
||||||
|
list_v.assign(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Construct with the value of other.
|
||||||
|
* utils::MemoryResource is obtained from other. After the move, other will be
|
||||||
|
* left empty.
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(TVector &&other) noexcept
|
||||||
|
: PropertyValue(std::move(other), other.get_allocator().GetMemoryResource()) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct with the value of other and use the given MemoryResource.
|
||||||
|
* If `other.get_allocator() != *memory`, this call will perform an
|
||||||
|
* element-wise move and other is not guaranteed to be empty.
|
||||||
|
*/
|
||||||
|
PropertyValue(TVector &&other, utils::MemoryResource *memory) : type_(Type::List), memory_{memory} {
|
||||||
|
new (&list_v) TVector(std::move(other), memory_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an element-wise move using default utils::NewDeleteResource().
|
||||||
|
* Other will not be left empty, i.e. keys will exist but their values may
|
||||||
|
* be Null.
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(std::map<std::string, PropertyValue> &&other)
|
||||||
|
: PropertyValue(std::move(other), utils::NewDeleteResource()) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an element-wise move using the given MemoryResource.
|
||||||
|
* Other will not be left empty, i.e. keys will exist but their values may
|
||||||
|
* be Null.
|
||||||
|
*/
|
||||||
|
PropertyValue(std::map<std::string, PropertyValue> &&other, utils::MemoryResource *memory)
|
||||||
|
: type_(Type::Map), memory_{memory} {
|
||||||
|
new (&map_v) TMap(memory_);
|
||||||
|
for (auto &kv : other) map_v.emplace(kv.first, std::move(kv.second));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct with the value of other.
|
||||||
|
* utils::MemoryResource is obtained from other. After the move, other will be
|
||||||
|
* left empty.
|
||||||
|
*/
|
||||||
|
explicit PropertyValue(TMap &&other) noexcept
|
||||||
|
: PropertyValue(std::move(other), other.get_allocator().GetMemoryResource()) {}
|
||||||
|
|
||||||
// copy constructor
|
// copy constructor
|
||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
PropertyValue(const PropertyValue &other);
|
PropertyValue(const PropertyValue &other);
|
||||||
|
PropertyValue(const PropertyValue &other, utils::MemoryResource *memory);
|
||||||
|
|
||||||
// move constructor
|
// move constructor
|
||||||
PropertyValue(PropertyValue &&other) noexcept;
|
PropertyValue(PropertyValue &&other) noexcept;
|
||||||
|
PropertyValue(PropertyValue &&other, utils::MemoryResource *memory) noexcept;
|
||||||
|
|
||||||
// copy assignment
|
// copy assignment
|
||||||
/// @throw std::bad_alloc
|
/// @throw std::bad_alloc
|
||||||
@ -153,7 +322,7 @@ class PropertyValue {
|
|||||||
|
|
||||||
// const value getters for non-primitive types
|
// const value getters for non-primitive types
|
||||||
/// @throw PropertyValueException if value isn't of correct type.
|
/// @throw PropertyValueException if value isn't of correct type.
|
||||||
const std::string &ValueString() const {
|
const TString &ValueString() const {
|
||||||
if (type_ != Type::String) {
|
if (type_ != Type::String) {
|
||||||
throw PropertyValueException("The value isn't a string!");
|
throw PropertyValueException("The value isn't a string!");
|
||||||
}
|
}
|
||||||
@ -161,7 +330,7 @@ class PropertyValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @throw PropertyValueException if value isn't of correct type.
|
/// @throw PropertyValueException if value isn't of correct type.
|
||||||
const std::vector<PropertyValue> &ValueList() const {
|
const TVector &ValueList() const {
|
||||||
if (type_ != Type::List) {
|
if (type_ != Type::List) {
|
||||||
throw PropertyValueException("The value isn't a list!");
|
throw PropertyValueException("The value isn't a list!");
|
||||||
}
|
}
|
||||||
@ -169,7 +338,7 @@ class PropertyValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @throw PropertyValueException if value isn't of correct type.
|
/// @throw PropertyValueException if value isn't of correct type.
|
||||||
const std::map<std::string, PropertyValue> &ValueMap() const {
|
const TMap &ValueMap() const {
|
||||||
if (type_ != Type::Map) {
|
if (type_ != Type::Map) {
|
||||||
throw PropertyValueException("The value isn't a map!");
|
throw PropertyValueException("The value isn't a map!");
|
||||||
}
|
}
|
||||||
@ -178,7 +347,7 @@ class PropertyValue {
|
|||||||
|
|
||||||
// reference value getters for non-primitive types
|
// reference value getters for non-primitive types
|
||||||
/// @throw PropertyValueException if value isn't of correct type.
|
/// @throw PropertyValueException if value isn't of correct type.
|
||||||
std::string &ValueString() {
|
TString &ValueString() {
|
||||||
if (type_ != Type::String) {
|
if (type_ != Type::String) {
|
||||||
throw PropertyValueException("The value isn't a string!");
|
throw PropertyValueException("The value isn't a string!");
|
||||||
}
|
}
|
||||||
@ -186,7 +355,7 @@ class PropertyValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @throw PropertyValueException if value isn't of correct type.
|
/// @throw PropertyValueException if value isn't of correct type.
|
||||||
std::vector<PropertyValue> &ValueList() {
|
TVector &ValueList() {
|
||||||
if (type_ != Type::List) {
|
if (type_ != Type::List) {
|
||||||
throw PropertyValueException("The value isn't a list!");
|
throw PropertyValueException("The value isn't a list!");
|
||||||
}
|
}
|
||||||
@ -194,7 +363,7 @@ class PropertyValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @throw PropertyValueException if value isn't of correct type.
|
/// @throw PropertyValueException if value isn't of correct type.
|
||||||
std::map<std::string, PropertyValue> &ValueMap() {
|
TMap &ValueMap() {
|
||||||
if (type_ != Type::Map) {
|
if (type_ != Type::Map) {
|
||||||
throw PropertyValueException("The value isn't a map!");
|
throw PropertyValueException("The value isn't a map!");
|
||||||
}
|
}
|
||||||
@ -208,13 +377,14 @@ class PropertyValue {
|
|||||||
bool bool_v;
|
bool bool_v;
|
||||||
int64_t int_v;
|
int64_t int_v;
|
||||||
double double_v;
|
double double_v;
|
||||||
std::string string_v;
|
TString string_v;
|
||||||
std::vector<PropertyValue> list_v;
|
TVector list_v;
|
||||||
std::map<std::string, PropertyValue> map_v;
|
TMap map_v;
|
||||||
TemporalData temporal_data_v;
|
TemporalData temporal_data_v;
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type_;
|
Type type_;
|
||||||
|
utils::MemoryResource *memory_{utils::NewDeleteResource()};
|
||||||
};
|
};
|
||||||
|
|
||||||
// stream output
|
// stream output
|
||||||
@ -329,8 +499,14 @@ inline bool operator<(const PropertyValue &first, const PropertyValue &second) n
|
|||||||
return first.ValueTemporalData() < second.ValueTemporalData();
|
return first.ValueTemporalData() < second.ValueTemporalData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inline PropertyValue::PropertyValue(const PropertyValue &other)
|
||||||
|
: PropertyValue(
|
||||||
|
other,
|
||||||
|
std::allocator_traits<utils::Allocator<PropertyValue>>::select_on_container_copy_construction(other.memory_)
|
||||||
|
.GetMemoryResource()) {}
|
||||||
|
|
||||||
inline PropertyValue::PropertyValue(const PropertyValue &other) : type_(other.type_) {
|
inline PropertyValue::PropertyValue(const PropertyValue &other, utils::MemoryResource *memory)
|
||||||
|
: type_(other.type_), memory_{memory} {
|
||||||
switch (other.type_) {
|
switch (other.type_) {
|
||||||
case Type::Null:
|
case Type::Null:
|
||||||
return;
|
return;
|
||||||
@ -344,13 +520,13 @@ inline PropertyValue::PropertyValue(const PropertyValue &other) : type_(other.ty
|
|||||||
this->double_v = other.double_v;
|
this->double_v = other.double_v;
|
||||||
return;
|
return;
|
||||||
case Type::String:
|
case Type::String:
|
||||||
new (&string_v) std::string(other.string_v);
|
new (&string_v) TString(other.string_v, memory_);
|
||||||
return;
|
return;
|
||||||
case Type::List:
|
case Type::List:
|
||||||
new (&list_v) std::vector<PropertyValue>(other.list_v);
|
new (&list_v) TVector(other.list_v, memory_);
|
||||||
return;
|
return;
|
||||||
case Type::Map:
|
case Type::Map:
|
||||||
new (&map_v) std::map<std::string, PropertyValue>(other.map_v);
|
new (&map_v) TMap(other.map_v, memory_);
|
||||||
return;
|
return;
|
||||||
case Type::TemporalData:
|
case Type::TemporalData:
|
||||||
this->temporal_data_v = other.temporal_data_v;
|
this->temporal_data_v = other.temporal_data_v;
|
||||||
@ -358,7 +534,10 @@ inline PropertyValue::PropertyValue(const PropertyValue &other) : type_(other.ty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PropertyValue::PropertyValue(PropertyValue &&other) noexcept : type_(other.type_) {
|
inline PropertyValue::PropertyValue(PropertyValue &&other) noexcept : PropertyValue(std::move(other), other.memory_) {}
|
||||||
|
|
||||||
|
inline PropertyValue::PropertyValue(PropertyValue &&other, utils::MemoryResource *memory) noexcept
|
||||||
|
: type_(other.type_), memory_{memory} {
|
||||||
switch (other.type_) {
|
switch (other.type_) {
|
||||||
case Type::Null:
|
case Type::Null:
|
||||||
break;
|
break;
|
||||||
@ -372,13 +551,13 @@ inline PropertyValue::PropertyValue(PropertyValue &&other) noexcept : type_(othe
|
|||||||
this->double_v = other.double_v;
|
this->double_v = other.double_v;
|
||||||
break;
|
break;
|
||||||
case Type::String:
|
case Type::String:
|
||||||
new (&string_v) std::string(std::move(other.string_v));
|
new (&string_v) TString(std::move(other.string_v), memory_);
|
||||||
break;
|
break;
|
||||||
case Type::List:
|
case Type::List:
|
||||||
new (&list_v) std::vector<PropertyValue>(std::move(other.list_v));
|
new (&list_v) TVector(std::move(other.list_v), memory_);
|
||||||
break;
|
break;
|
||||||
case Type::Map:
|
case Type::Map:
|
||||||
new (&map_v) std::map<std::string, PropertyValue>(std::move(other.map_v));
|
new (&map_v) TMap(std::move(other.map_v), memory_);
|
||||||
break;
|
break;
|
||||||
case Type::TemporalData:
|
case Type::TemporalData:
|
||||||
this->temporal_data_v = other.temporal_data_v;
|
this->temporal_data_v = other.temporal_data_v;
|
||||||
@ -409,13 +588,13 @@ inline PropertyValue &PropertyValue::operator=(const PropertyValue &other) {
|
|||||||
this->double_v = other.double_v;
|
this->double_v = other.double_v;
|
||||||
break;
|
break;
|
||||||
case Type::String:
|
case Type::String:
|
||||||
new (&string_v) std::string(other.string_v);
|
new (&string_v) TString(other.string_v, memory_);
|
||||||
break;
|
break;
|
||||||
case Type::List:
|
case Type::List:
|
||||||
new (&list_v) std::vector<PropertyValue>(other.list_v);
|
new (&list_v) TVector(other.list_v, memory_);
|
||||||
break;
|
break;
|
||||||
case Type::Map:
|
case Type::Map:
|
||||||
new (&map_v) std::map<std::string, PropertyValue>(other.map_v);
|
new (&map_v) TMap(other.map_v, memory_);
|
||||||
break;
|
break;
|
||||||
case Type::TemporalData:
|
case Type::TemporalData:
|
||||||
this->temporal_data_v = other.temporal_data_v;
|
this->temporal_data_v = other.temporal_data_v;
|
||||||
@ -444,13 +623,13 @@ inline PropertyValue &PropertyValue::operator=(PropertyValue &&other) noexcept {
|
|||||||
this->double_v = other.double_v;
|
this->double_v = other.double_v;
|
||||||
break;
|
break;
|
||||||
case Type::String:
|
case Type::String:
|
||||||
new (&string_v) std::string(std::move(other.string_v));
|
new (&string_v) TString(std::move(other.string_v), memory_);
|
||||||
break;
|
break;
|
||||||
case Type::List:
|
case Type::List:
|
||||||
new (&list_v) std::vector<PropertyValue>(std::move(other.list_v));
|
new (&list_v) TVector(std::move(other.list_v), memory_);
|
||||||
break;
|
break;
|
||||||
case Type::Map:
|
case Type::Map:
|
||||||
new (&map_v) std::map<std::string, PropertyValue>(std::move(other.map_v));
|
new (&map_v) TMap(std::move(other.map_v), memory_);
|
||||||
break;
|
break;
|
||||||
case Type::TemporalData:
|
case Type::TemporalData:
|
||||||
this->temporal_data_v = other.temporal_data_v;
|
this->temporal_data_v = other.temporal_data_v;
|
||||||
|
Loading…
Reference in New Issue
Block a user