Added the action logging system

This commit is contained in:
WolverinDEV 2020-06-28 14:01:11 +02:00
parent f11bee75c1
commit 809fa82b31
4 changed files with 124 additions and 50 deletions

View File

@ -1205,14 +1205,41 @@ const v2::PermissionContainer v2::PermissionManager::channel_permission(const Pe
return empty_channel_permission;
}
void v2::PermissionManager::set_permission(const PermissionType &permission, const v2::PermissionValues &values, const v2::PermissionUpdateType &action_value, const v2::PermissionUpdateType &action_grant, int flag_skip, int flag_negate) {
inline v2::PermissionContainer duplicate_permission_container(const v2::PermissionContainer& original) {
v2::PermissionContainer result{};
result.flags = original.flags;
result.values.grant = original.values.grant;
result.values.value = original.values.value;
return result;
}
static v2::PermissionContainer kEmptyPermissionContainer{
.flags = v2::PermissionFlags{
.database_reference = false,
.channel_specific = false,
.value_set = false,
.grant_set = false,
.skip = false,
.negate = false,
.flag_value_update = false,
.flag_grant_update = false
},
.values = v2::PermissionValues{0, 0}
};
v2::PermissionContainer v2::PermissionManager::set_permission(const PermissionType &permission, const v2::PermissionValues &values, const v2::PermissionUpdateType &action_value, const v2::PermissionUpdateType &action_grant, int flag_skip, int flag_negate) {
if(permission < 0 || permission >= PermissionType::permission_id_max)
return;
return kEmptyPermissionContainer;
const auto block = this->calculate_block(permission);
this->ref_allocate_block(block);
auto& data = this->block_containers[block]->permissions[this->calculate_block_index(permission)];
auto old_state = duplicate_permission_container(data);
if(action_value == v2::PermissionUpdateType::set_value) {
data.flags.value_set = true;
data.flags.flag_value_update = true;
@ -1245,11 +1272,13 @@ void v2::PermissionManager::set_permission(const PermissionType &permission, con
this->unref_block(block);
this->trigger_db_update();
return old_state;
}
void v2::PermissionManager::set_channel_permission(const PermissionType &permission, ChannelId channel_id, const v2::PermissionValues &values, const v2::PermissionUpdateType &action_value, const v2::PermissionUpdateType &action_grant, int flag_skip, int flag_negate) {
v2::PermissionContainer v2::PermissionManager::set_channel_permission(const PermissionType &permission, ChannelId channel_id, const v2::PermissionValues &values, const v2::PermissionUpdateType &action_value, const v2::PermissionUpdateType &action_grant, int flag_skip, int flag_negate) {
if(permission < 0 || permission >= PermissionType::permission_id_max)
return;
return kEmptyPermissionContainer;
unique_lock channel_perm_lock(this->channel_list_lock);
ChannelPermissionContainer* permission_container = nullptr;
@ -1259,13 +1288,13 @@ void v2::PermissionManager::set_channel_permission(const PermissionType &permiss
break;
}
/* register a new permission if we have no permission already*/
if(!permission_container || !permission_container->flags.permission_set()) { /* if the permission isn't set then we have to register it again */
if(action_value != v2::PermissionUpdateType::set_value && action_grant == v2::PermissionUpdateType::set_value) {
return; /* we were never willing to set this permission */
/* register a new permission if we have no permission already */
if(!permission_container) { /* if the permission isn't set then we have to register it again */
if(action_value != v2::PermissionUpdateType::set_value && action_grant != v2::PermissionUpdateType::set_value) {
return kEmptyPermissionContainer; /* we were never willing to set this permission */
}
if(!permission_container) {
{
auto container = make_unique<ChannelPermissionContainer>();
container->permission = permission;
container->channel_id = channel_id;
@ -1274,13 +1303,16 @@ void v2::PermissionManager::set_channel_permission(const PermissionType &permiss
}
/* now set the channel flag for that permission */
const auto block = this->calculate_block(permission);
this->ref_allocate_block(block);
{
const auto block = this->calculate_block(permission);
this->ref_allocate_block(block);
auto& data = this->block_containers[block]->permissions[this->calculate_block_index(permission)];
data.flags.channel_specific = true;
this->unref_block(block);
auto& data = this->block_containers[block]->permissions[this->calculate_block_index(permission)];
data.flags.channel_specific = true;
this->unref_block(block);
}
}
auto old_state = duplicate_permission_container(*permission_container);
if(action_value == v2::PermissionUpdateType::set_value) {
permission_container->flags.value_set = true;
@ -1321,6 +1353,7 @@ void v2::PermissionManager::set_channel_permission(const PermissionType &permiss
}
}
this->trigger_db_update();
return old_state;
}
const std::vector<std::tuple<PermissionType, const v2::PermissionContainer>> v2::PermissionManager::permissions() {

View File

@ -757,7 +757,7 @@ namespace ts {
bool flag_value_update: 1;
bool flag_grant_update: 1;
ts_always_inline bool permission_set() {
[[nodiscard]] ts_always_inline bool permission_set() const {
return this->value_set || this->grant_set;
}
};
@ -863,24 +863,24 @@ namespace ts {
/* general getters/setters */
const PermissionFlags permission_flags(const PermissionType&); /* we return a "copy" because the actual permission could be deleted while we're analyzing the flags */
ts_always_inline const PermissionFlags permission_flags(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_flags(permission_info->type); }
ts_always_inline PermissionFlags permission_flags(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_flags(permission_info->type); }
const PermissionValues permission_values(const PermissionType&);
ts_always_inline const PermissionValues permission_values(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_values(permission_info->type); }
ts_always_inline PermissionValues permission_values(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_values(permission_info->type); }
const PermissionFlaggedValue permission_value_flagged(const PermissionType&);
ts_always_inline const PermissionFlaggedValue permission_value_flagged(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_value_flagged(permission_info->type); }
ts_always_inline PermissionFlaggedValue permission_value_flagged(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_value_flagged(permission_info->type); }
const PermissionFlaggedValue permission_granted_flagged(const PermissionType&);
ts_always_inline const PermissionFlaggedValue permission_granted_flagged(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_granted_flagged(permission_info->type); }
ts_always_inline PermissionFlaggedValue permission_granted_flagged(const std::shared_ptr<PermissionTypeEntry>& permission_info) { return this->permission_granted_flagged(permission_info->type); }
/* only worth looking up if channel_specific is set */
const PermissionContainer channel_permission(const PermissionType& /* permission */, ChannelId /* channel id */);
ts_always_inline const PermissionContainer channel_permission(const std::shared_ptr<PermissionTypeEntry>& permission_info, ChannelId channel_id) { return this->channel_permission(permission_info->type, channel_id); }
ts_always_inline PermissionContainer channel_permission(const std::shared_ptr<PermissionTypeEntry>& permission_info, ChannelId channel_id) { return this->channel_permission(permission_info->type, channel_id); }
/* modifiers */
void set_permission(const PermissionType& /* permission */, const PermissionValues& /* values */, const PermissionUpdateType& /* update value */, const PermissionUpdateType& /* update grant */, int /* flag skip */ = -1, int /* flag negate */ = -1);
void set_channel_permission(const PermissionType& /* permission */, ChannelId /* channel id */, const PermissionValues& /* values */, const PermissionUpdateType& /* update value */, const PermissionUpdateType& /* update grant */, int /* flag skip */ = -1, int /* flag negate */ = -1);
PermissionContainer set_permission(const PermissionType& /* permission */, const PermissionValues& /* values */, const PermissionUpdateType& /* update value */, const PermissionUpdateType& /* update grant */, int /* flag skip */ = -1, int /* flag negate */ = -1);
PermissionContainer set_channel_permission(const PermissionType& /* permission */, ChannelId /* channel id */, const PermissionValues& /* values */, const PermissionUpdateType& /* update value */, const PermissionUpdateType& /* update grant */, int /* flag skip */ = -1, int /* flag negate */ = -1);
/* bulk info */
const std::vector<std::tuple<PermissionType, const PermissionContainer>> permissions();

View File

@ -181,22 +181,22 @@ namespace ts {
friend class command_builder_impl;
public:
inline void reserve(size_t length, bool accumulative = true) {
this->bulk.reserve(length + (accumulative ? this->bulk.size() : 0));
this->bulk->reserve(length + (accumulative ? this->bulk->size() : 0));
}
inline void reset() {
this->bulk.clear();
this->bulk->clear();
}
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)) {
if(impl::value_raw_impl(*this->bulk, key, begin, &end)) {
std::string result{};
result.reserve(this->bulk.size());
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;
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);
}
@ -239,25 +239,42 @@ namespace ts {
auto data = converter<T>::to_string(value);
this->put_unchecked(key, std::string_view{data});
}
protected:
explicit command_builder_bulk(bool& change_flag, std::string& bulk) : flag_changed{&change_flag}, bulk{&bulk} {}
private:
bool& flag_changed;
std::string& bulk;
explicit command_builder_bulk(bool& change_flag, std::string& bulk) : flag_changed{change_flag}, bulk{bulk} {}
bool* flag_changed;
std::string* 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);
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->bulk->append(escaped_value);
}
this->bulk.append(" ");
this->flag_changed = true;
this->bulk->append(" ");
*this->flag_changed = true;
}
};
class standalone_command_builder_bulk : public command_builder_bulk {
public:
explicit standalone_command_builder_bulk(size_t expected_length = 0) : command_builder_bulk{this->flag_changed_, this->buffer_} {
if(expected_length > 0)
this->buffer_.reserve(expected_length);
}
[[nodiscard]] inline const std::string& buffer() const { return this->buffer_; }
[[nodiscard]] inline std::string& buffer() { return this->buffer_; }
private:
bool flag_changed_{};
std::string buffer_{};
};
template <typename vector_t = std::vector<std::string>>
class command_builder_impl {
public:
@ -324,6 +341,18 @@ namespace ts {
return result;
}
inline void push_bulk(standalone_command_builder_bulk&& bulk) {
this->bulks.push_back(std::move(bulk.buffer()));
this->flag_changed = true;
}
inline void set_bulk(size_t index, standalone_command_builder_bulk&& bulk) {
while(this->bulks.size() <= index)
this->bulks.emplace_back("").reserve(expected_bulk_size);
this->bulks[index] = std::move(bulk.buffer());
this->flag_changed = true;
}
inline void reset() {
for(auto& bulk : this->bulks)
bulk = " ";

View File

@ -262,25 +262,27 @@ namespace sql {
friend class ::sql::command;
friend class ::sql::model;
public:
explicit command_base(nullptr_t) : _data{nullptr} {}
command_base(SqlManager* handle, const std::string &sql, std::initializer_list<variable> values) {
assert(handle);
assert(!sql.empty());
this->_data = handle->allocateCommandData();
this->_data->handle = handle;
this->_data->sql_command = sql;
this->__data = this->_data.get();
for(const auto& val : values) this->value(val);
for(const auto& val : values)
this->value(val);
}
template<typename... Ts>
command_base(SqlManager* handle, std::string sql, Ts&&... vars) : command_base(handle, sql, {}) { values(vars...); }
command_base(SqlManager* handle, const std::string& sql, Ts&&... vars) : command_base(handle, sql, {}) { values(vars...); }
command_base(const command_base<SelfType>& ref) : _data(ref._data), __data(ref._data.get()) {}
command_base(command_base<SelfType>&& ref) noexcept : _data(ref._data), __data(ref._data.get()) { }
command_base(const command_base<SelfType>& ref) : _data(ref._data) {}
command_base(command_base<SelfType>&& ref) noexcept : _data(ref._data) { }
virtual ~command_base() = default;
virtual SelfType& value(const variable& val) {
SelfType& value(const variable& val) {
this->_data->variables.push_back(val);
return *(SelfType*) this;
}
@ -303,10 +305,20 @@ namespace sql {
std::string sqlCommand(){ return _data->sql_command; }
SqlManager* handle(){ return _data->handle; }
command_base& operator=(const command_base& other) {
this->_data = other._data;
return *this;
}
command_base& operator=(command_base&& other) {
this->_data = std::move(other._data);
return *this;
}
protected:
explicit command_base(const std::shared_ptr<CommandData>& data) : _data(data), __data(data.get()) {}
explicit command_base(std::shared_ptr<CommandData> data) : _data(std::move(data)) {}
std::shared_ptr<CommandData> _data;
CommandData* __data = nullptr;
};
}
@ -317,13 +329,13 @@ namespace sql {
template<typename... Ts>
model(SqlManager* handle, const std::string &sql, Ts... vars) : model(handle, sql, {}) { values(vars...); }
model(const model& v) : command_base(v) {};
model(model&& v) noexcept : command_base(v){};
~model() override {};
explicit model(nullptr_t) : command_base{nullptr} {};
//model(const model& v) : command_base{v} {};
//model(model&& v) noexcept : command_base{std::forward<model>(v)} {};
~model() override = default;
sql::command command();
sql::model copy();
private:
explicit model(const std::shared_ptr<CommandData>&);
};