M database/database.xml => database/database.xml +18 -0
@@ 14,9 14,27 @@
<field name="realname" type="string" length="1024" default=""/>
<field name="verifyCert" type="boolean" default="true"/>
+ <field name="encodingOut" type="string" default="utf-8"/>
+ <field name="encodingIn" type="string" default="utf-8"/>
+
+ <index unique="true">
+ <indexfield name="owner"/>
+ <indexfield name="server"/>
+ </index>
+ </object>
+
+ <object name="IrcChannelOptions">
+ <field name="owner" type="string" length="3071"/>
+ <field name="server" type="string" length="3071"/>
+ <field name="channel" type="string" length="1024"/>
+
+ <field name="encodingOut" type="string"/>
+ <field name="encodingIn" type="string"/>
+
<index unique="true">
<indexfield name="owner"/>
<indexfield name="server"/>
+ <indexfield name="channel"/>
</index>
</object>
M src/database/database.cpp => src/database/database.cpp +33 -0
@@ 49,6 49,39 @@ db::IrcServerOptions Database::get_irc_server_options(const std::string& owner,
}
}
+db::IrcChannelOptions Database::get_irc_channel_options(const std::string& owner,
+ const std::string& server,
+ const std::string& channel)
+{
+ try {
+ auto options = litesql::select<db::IrcChannelOptions>(Database::get_db(),
+ db::IrcChannelOptions::Owner == owner &&
+ db::IrcChannelOptions::Server == server &&
+ db::IrcChannelOptions::Channel == channel).one();
+ return options;
+ } catch (const litesql::NotFound& e) {
+ db::IrcChannelOptions options(Database::get_db());
+ options.owner = owner;
+ options.server = server;
+ options.channel = channel;
+ return options;
+ }
+}
+
+db::IrcChannelOptions Database::get_irc_channel_options_with_server_default(const std::string& owner,
+ const std::string& server,
+ const std::string& channel)
+{
+ auto coptions = Database::get_irc_channel_options(owner, server, channel);
+ auto soptions = Database::get_irc_server_options(owner, server);
+ if (coptions.encodingIn.value().empty())
+ coptions.encodingIn = soptions.encodingIn;
+ if (coptions.encodingOut.value().empty())
+ coptions.encodingOut = soptions.encodingOut;
+
+ return coptions;
+}
+
void Database::close()
{
Database::db.reset(nullptr);
M src/database/database.hpp => src/database/database.hpp +6 -0
@@ 29,6 29,12 @@ public:
*/
static db::IrcServerOptions get_irc_server_options(const std::string& owner,
const std::string& server);
+ static db::IrcChannelOptions get_irc_channel_options(const std::string& owner,
+ const std::string& server,
+ const std::string& channel);
+ static db::IrcChannelOptions get_irc_channel_options_with_server_default(const std::string& owner,
+ const std::string& server,
+ const std::string& channel);
static void close();
M tests/database.cpp => tests/database.cpp +73 -11
@@ 9,20 9,82 @@ TEST_CASE("Database")
#ifdef USE_DATABASE
Config::set("db_name", ":memory:");
Database::set_verbose(false);
- auto o = Database::get_irc_server_options("zouzou@example.com", "irc.example.com");
- o.update();
- auto a = Database::get_irc_server_options("zouzou@example.com", "irc.example.com");
- auto b = Database::get_irc_server_options("moumou@example.com", "irc.example.com");
- // b does not yet exist in the db, the object is created but not yet
- // inserted
- CHECK(1 == Database::count<db::IrcServerOptions>());
+ SECTION("Basic retrieve and update")
+ {
+ auto o = Database::get_irc_server_options("zouzou@example.com", "irc.example.com");
+ o.update();
+ auto a = Database::get_irc_server_options("zouzou@example.com", "irc.example.com");
+ auto b = Database::get_irc_server_options("moumou@example.com", "irc.example.com");
- b.update();
- CHECK(2 == Database::count<db::IrcServerOptions>());
+ // b does not yet exist in the db, the object is created but not yet
+ // inserted
+ CHECK(1 == Database::count<db::IrcServerOptions>());
- CHECK(b.pass == "");
- CHECK(b.pass.value() == "");
+ b.update();
+ CHECK(2 == Database::count<db::IrcServerOptions>());
+
+ CHECK(b.pass == "");
+ CHECK(b.pass.value() == "");
+ }
+
+ SECTION("channel options")
+ {
+ Config::set("db_name", ":memory:");
+ auto o = Database::get_irc_channel_options("zouzou@example.com", "irc.example.com", "#foo");
+
+ CHECK(o.encodingIn == "");
+ o.encodingIn = "ISO-8859-1";
+ o.update();
+ auto b = Database::get_irc_channel_options("zouzou@example.com", "irc.example.com", "#foo");
+ CHECK(o.encodingIn == "ISO-8859-1");
+ }
+
+ SECTION("Channel options with server default")
+ {
+ const std::string owner{"zouzou@example.com"};
+ const std::string server{"irc.example.com"};
+ const std::string chan1{"#foo"};
+
+ auto c = Database::get_irc_channel_options(owner, server, chan1);
+ auto s = Database::get_irc_server_options(owner, server);
+
+ GIVEN("An option defined for the channel but not the server")
+ {
+ c.encodingIn = "channelEncoding";
+ c.update();
+ WHEN("we fetch that option")
+ {
+ auto r = Database::get_irc_channel_options_with_server_default(owner, server, chan1);
+ THEN("we get the channel option")
+ CHECK(r.encodingIn == "channelEncoding");
+ }
+ }
+ GIVEN("An option defined for the server but not the channel")
+ {
+ s.encodingIn = "serverEncoding";
+ s.update();
+ WHEN("we fetch that option")
+ {
+ auto r = Database::get_irc_channel_options_with_server_default(owner, server, chan1);
+ THEN("we get the server option")
+ CHECK(r.encodingIn == "serverEncoding");
+ }
+ }
+ GIVEN("An option defined for both the server and the channel")
+ {
+ s.encodingIn = "serverEncoding";
+ s.update();
+ c.encodingIn = "channelEncoding";
+ c.update();
+ WHEN("we fetch that option")
+ {
+ auto r = Database::get_irc_channel_options_with_server_default(owner, server, chan1);
+ THEN("we get the channel option")
+ CHECK(r.encodingIn == "channelEncoding");
+ }
+ }
+ }
Database::close();
#endif