~singpolyma/biboumi

40db183e3753486deaa43e950fff38579c5ced6f — louiz’ 5 years ago 4a963cc
Using OptionalBool, add RecordHistoryOptional col into IrcChannelOptions table

ref #3269
M src/database/database.hpp => src/database/database.hpp +6 -1
@@ 7,6 7,8 @@
#include <database/column.hpp>
#include <database/count_query.hpp>

#include <utils/optional_bool.hpp>

#include <chrono>
#include <string>



@@ 82,6 84,9 @@ class Database
    static constexpr auto options = "";
    RecordHistory(): Column<bool>(true) {}};

  struct RecordHistoryOptional: Column<OptionalBool> { static constexpr auto name = "recordHistory_";
    static constexpr auto options = ""; };

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


@@ 99,7 104,7 @@ class Database
  using IrcServerOptionsTable = Table<Id, Owner, Server, Pass, AfterConnectionCommand, TlsPorts, Ports, Username, Realname, VerifyCert, TrustedFingerprint, EncodingOut, EncodingIn, MaxHistoryLength>;
  using IrcServerOptions = IrcServerOptionsTable::RowType;

  using IrcChannelOptionsTable = Table<Id, Owner, Server, Channel, EncodingOut, EncodingIn, MaxHistoryLength, Persistent>;
  using IrcChannelOptionsTable = Table<Id, Owner, Server, Channel, EncodingOut, EncodingIn, MaxHistoryLength, Persistent, RecordHistoryOptional>;
  using IrcChannelOptions = IrcChannelOptionsTable::RowType;

  Database() = default;

M src/database/query.cpp => src/database/query.cpp +10 -0
@@ 9,3 9,13 @@ void actual_add_param(Query& query, const std::string& val)
{
  query.params.push_back(val);
}

void actual_add_param(Query& query, const OptionalBool& val)
{
  if (!val.is_set)
    query.params.push_back("0");
  else if (val.value)
    query.params.push_back("1");
  else
    query.params.push_back("-1");
}
\ No newline at end of file

M src/database/query.hpp => src/database/query.hpp +2 -0
@@ 1,5 1,6 @@
#pragma once

#include <utils/optional_bool.hpp>
#include <database/statement.hpp>
#include <database/column.hpp>



@@ 49,3 50,4 @@ 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);

M src/database/select_query.hpp => src/database/select_query.hpp +16 -1
@@ 5,6 5,8 @@
#include <logger/logger.hpp>
#include <database/row.hpp>

#include <utils/optional_bool.hpp>

#include <vector>
#include <string>



@@ 20,7 22,7 @@ extract_row_value(Statement& statement, const int i)
}

template <typename T>
typename std::enable_if<std::is_same<std::string, T>::value, std::string>::type
typename std::enable_if<std::is_same<std::string, T>::value, T>::type
extract_row_value(Statement& statement, const int i)
{
  const auto size = sqlite3_column_bytes(statement.get(), i);


@@ 29,6 31,19 @@ extract_row_value(Statement& statement, const int i)
  return result;
}

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

template <std::size_t N=0, typename... T>
typename std::enable_if<N < sizeof...(T), void>::type
extract_row_values(Row<T...>& row, Statement& statement)

M src/database/type_to_sql.cpp => src/database/type_to_sql.cpp +1 -0
@@ 6,3 6,4 @@ template <> const std::string TypeToSQLType<long>::type = "INTEGER";
template <> const std::string TypeToSQLType<long long>::type = "INTEGER";
template <> const std::string TypeToSQLType<bool>::type = "INTEGER";
template <> const std::string TypeToSQLType<std::string>::type = "TEXT";
template <> const std::string TypeToSQLType<OptionalBool>::type = "INTEGER";
\ No newline at end of file

M src/database/type_to_sql.hpp => src/database/type_to_sql.hpp +4 -1
@@ 1,5 1,7 @@
#pragma once

#include <utils/optional_bool.hpp>

#include <string>

template <typename T>


@@ 10,4 12,5 @@ template <> const std::string TypeToSQLType<std::size_t>::type;
template <> const std::string TypeToSQLType<long>::type;
template <> const std::string TypeToSQLType<long long>::type;
template <> const std::string TypeToSQLType<bool>::type;
template <> const std::string TypeToSQLType<std::string>::type;
\ No newline at end of file
template <> const std::string TypeToSQLType<std::string>::type;
template <> const std::string TypeToSQLType<OptionalBool>::type;
\ No newline at end of file

A src/utils/optional_bool.hpp => src/utils/optional_bool.hpp +25 -0
@@ 0,0 1,25 @@
#pragma once

#include <string>

struct OptionalBool
{
  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;
  }

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

M tests/database.cpp => tests/database.cpp +4 -0
@@ 33,9 33,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);
      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);
    }

  SECTION("Channel options with server default")