~singpolyma/biboumi

ba879a882e031d7b8503f78fe41d1210000c96ca — louiz’ 4 years ago 3f088e7
Use std::optional<bool> instead of OptionalBool
M src/database/database.hpp => src/database/database.hpp +1 -1
@@ 69,7 69,7 @@ class Database
  struct RecordHistory: Column<bool> { static constexpr auto name = "recordhistory_";
    RecordHistory(): Column<bool>(true) {}};

  struct RecordHistoryOptional: Column<OptionalBool> { static constexpr auto name = "recordhistory_"; };
  struct RecordHistoryOptional: Column<std::optional<bool>> { static constexpr auto name = "recordhistory_"; };

  struct VerifyCert: Column<bool> { static constexpr auto name = "verifycert_";
    VerifyCert(): Column<bool>(true) {} };

M src/database/query.cpp => src/database/query.cpp +6 -6
@@ 11,11 11,11 @@ void actual_bind(Statement& statement, const std::int64_t& value, int index)
  statement.bind_int64(index, value);
}

void actual_bind(Statement& statement, const OptionalBool& value, int index)
void actual_bind(Statement& statement, const std::optional<bool>& value, int index)
{
  if (!value.is_set)
  if (!value)
    statement.bind_int64(index, 0);
  else if (value.value)
  else if (*value)
    statement.bind_int64(index, 1);
  else
    statement.bind_int64(index, -1);


@@ 26,11 26,11 @@ void actual_add_param(Query& query, const std::string& val)
  query.params.push_back(val);
}

void actual_add_param(Query& query, const OptionalBool& val)
void actual_add_param(Query& query, const std::optional<bool>& val)
{
  if (!val.is_set)
  if (!val)
    query.params.push_back("0");
  else if (val.value)
  else if (*val)
    query.params.push_back("1");
  else
    query.params.push_back("-1");

M src/database/query.hpp => src/database/query.hpp +2 -2
@@ 18,7 18,7 @@ void actual_bind(Statement& statement, const T& value, int index)
{
  actual_bind(statement, static_cast<std::int64_t>(value), index);
}
void actual_bind(Statement& statement, const OptionalBool& value, int index);
void actual_bind(Statement& statement, const std::optional<bool>& value, int index);

#ifdef DEBUG_SQL_QUERIES
#include <utils/scopetimer.hpp>


@@ 71,7 71,6 @@ void actual_add_param(Query& query, const T& val)
}

void actual_add_param(Query& query, const std::string& val);
void actual_add_param(Query& query, const OptionalBool& val);

template <typename T>
typename std::enable_if<!std::is_integral<T>::value, Query&>::type


@@ 80,6 79,7 @@ operator<<(Query& query, const T&)
  query.body += T::name;
  return query;
}
void actual_add_param(Query& query, const std::optional<bool>& val);

Query& operator<<(Query& query, const char* str);
Query& operator<<(Query& query, const std::string& str);

M src/database/select_query.hpp => src/database/select_query.hpp +4 -5
@@ 29,16 29,15 @@ extract_row_value(Statement& statement, const int i)
}

template <typename T>
typename std::enable_if<std::is_same<OptionalBool, T>::value, T>::type
typename std::enable_if<std::is_same<std::optional<bool>, T>::value, T>::type
extract_row_value(Statement& statement, const int i)
{
  const auto integer = statement.get_column_int(i);
  OptionalBool result;
  if (integer > 0)
    result.set_value(true);
    return true;
  else if (integer < 0)
    result.set_value(false);
  return result;
    return false;
  return std::nullopt;
}

template <std::size_t N=0, typename... T>

M src/utils/optional_bool.cpp => src/utils/optional_bool.cpp +2 -2
@@ 1,8 1,8 @@
#include <utils/optional_bool.hpp>


std::ostream& operator<<(std::ostream& os, const OptionalBool& o)
std::ostream& operator<<(std::ostream& os, const std::optional<bool>& o)
{
  os << o.to_string();
  os << std::to_string(o);
  return os;
}

M src/utils/optional_bool.hpp => src/utils/optional_bool.hpp +16 -32
@@ 1,37 1,21 @@
#pragma once

#include <optional>

#include <string>

struct OptionalBool
namespace std
{
  OptionalBool() = default;

  OptionalBool(bool value):
  is_set(true), value(value) {}

  void set_value(bool value)
  {
    this->is_set = true;
    this->value = value;
  }

  void unset()
  {
    this->is_set = false;
  }

  std::string to_string() const
  {
    if (this->is_set == false)
      return "unset";
    else if (this->value)
      return "true";
    else
      return "false";
  }

  bool is_set{false};
  bool value{false};
};

std::ostream& operator<<(std::ostream& os, const OptionalBool& o);
inline
std::string to_string(const std::optional<bool> b)
{
  if (!b)
    return "unset";
  else if (*b)
    return "true";
  else
    return "false";
}
}

std::ostream& operator<<(std::ostream& os, const std::optional<bool>& o);

M src/xmpp/biboumi_adhoc_commands.cpp => src/xmpp/biboumi_adhoc_commands.cpp +7 -7
@@ 493,7 493,7 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester, 
    {
      // Value selected by default
      XmlSubNode value(record_history, "value");
      value.set_inner(options.col<Database::RecordHistoryOptional>().to_string());
      value.set_inner(std::to_string(options.col<Database::RecordHistoryOptional>()));
    }
    // All three possible values
    for (const auto& val: {"unset", "true", "false"})


@@ 594,19 594,19 @@ bool handle_irc_channel_configuration_form(XmppComponent& xmpp_component, const 
              else if (field->get_tag("var") == "record_history" &&
                       value && !value->get_inner().empty())
                {
                  OptionalBool& database_value = options.col<Database::RecordHistoryOptional>();
                  std::optional<bool>& database_value = options.col<Database::RecordHistoryOptional>();
                  if (value->get_inner() == "true")
                    database_value.set_value(true);
                    database_value = true;
                  else if (value->get_inner() == "false")
                    database_value.set_value(false);
                    database_value = false;
                  else
                    database_value.unset();
                    database_value.reset();
                  auto& biboumi_component = dynamic_cast<BiboumiComponent&>(xmpp_component);
                  Bridge* bridge = biboumi_component.find_user_bridge(requester.bare());
                  if (bridge)
                    {
                      if (database_value.is_set)
                        bridge->set_record_history(database_value.value);
                      if (database_value)
                        bridge->set_record_history(*database_value);
                      else
                        { // It is unset, we need to fetch the Global option, to
                          // know if it’s enabled or not

M tests/database.cpp => tests/database.cpp +4 -4
@@ 56,13 56,13 @@ TEST_CASE("Database")

      CHECK(o.col<Database::EncodingIn>() == "");
      o.col<Database::EncodingIn>() = "ISO-8859-1";
      CHECK(o.col<Database::RecordHistoryOptional>().is_set == false);
      o.col<Database::RecordHistoryOptional>().set_value(false);
      CHECK(!o.col<Database::RecordHistoryOptional>());
      o.col<Database::RecordHistoryOptional>() = false;
      o.save(Database::db);
      auto b = Database::get_irc_channel_options("zouzou@example.com", "irc.example.com", "#foo");
      CHECK(o.col<Database::EncodingIn>() == "ISO-8859-1");
      CHECK(o.col<Database::RecordHistoryOptional>().is_set == true);
      CHECK(o.col<Database::RecordHistoryOptional>().value == false);
      CHECK(o.col<Database::RecordHistoryOptional>());
      CHECK(*o.col<Database::RecordHistoryOptional>() == false);
    }

  SECTION("Channel options with server default")