Mercurial > malikania
changeset 159:7362fba6ff11
Server: separate database access from model objects, #760 @4h
For a cleaner object usage regarding model access, we now use plain objects
instead of smart pointers of polymorphic objects.
For example, account, character and spell class are static objects which have a
reference to the real database backend, therefore each time a function requires
database access, it is forwarded to the appropriate database functions using
account_dao, character_dao and spell_dao.
To avoid user destroying the data by itself, the model::set_id function is only
available if MALIKANIA_PRIVATE macro is defined, thus database backends have
access but usually not the user code.
line wrap: on
line diff
--- a/libdb-sqlite/CMakeLists.txt Tue Jan 09 13:15:07 2018 +0100 +++ b/libdb-sqlite/CMakeLists.txt Sat Mar 03 17:34:12 2018 +0100 @@ -23,20 +23,24 @@ set( HEADERS ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/common.hpp - ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_account.hpp + ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_account_dao.hpp + ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_character_dao.hpp ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_database.hpp + ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_spell_dao.hpp ) set( SOURCES ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/common.cpp - ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_account.cpp - ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_character.cpp + ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_account_dao.cpp + ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_character_dao.cpp ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_database.cpp + ${libmlk-db-sqlite_SOURCE_DIR}/malikania/server/db/sqlite_spell_dao.cpp ) malikania_define_library( TARGET libmlk-db-sqlite + FLAGS MALIKANIA_PRIVATE SOURCES ${HEADERS} ${SOURCES} LIBRARIES libmlk-server sqlite PUBLIC_INCLUDES ${libmlk-db-sqlite_SOURCE_DIR}
--- a/libdb-sqlite/malikania/server/db/sqlite_account.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -/* - * sqlite_account.cpp -- database account object (SQLite implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "sqlite_database.hpp" - -namespace mlk { - -namespace server { - -using sqlite_dao = sqlite_account::sqlite_dao; - -/* - * sqlite_account::do_save - * ------------------------------------------------------------------ - */ -void sqlite_account::do_save() -{ - const std::string sql( - "INSERT INTO account(login, password, email, firstname, lastname)" - "VALUES (?, ?, ?, ?, ?)" - ); - - exec(db_.instance(), sql, {login_, password_, email_, firstname_, lastname_}); - id_ = sqlite3_last_insert_rowid(db_.instance()); -} - -/* - * sqlite_account::do_remove - * ------------------------------------------------------------------ - */ -void sqlite_account::do_remove() -{ - const std::string sql( - "DELETE" - " FROM account" - " WHERE id = ?" - ); - - exec(db_.instance(), sql, {id_}); -} - -/* - * sqlite_account::do_set_password - * ------------------------------------------------------------------ - */ -void sqlite_account::do_set_password(const std::string& password) -{ - const std::string sql( - "UPDATE account" - " SET password = ?" - " WHERE id = ?" - ); - - exec(db_.instance(), sql, {password, id_}); -} - -/* - * sqlite_account::do_set_email - * ------------------------------------------------------------------ - */ -void sqlite_account::do_set_email(const std::string& email) -{ - const std::string sql( - "UPDATE account" - " SET email = ?" - " WHERE id = ?" - ); - - exec(db_.instance(), sql, {email, id_}); -} - -/* - * sqlite_account::do_set_firstname - * ------------------------------------------------------------------ - */ -void sqlite_account::do_set_firstname(const std::string& name) -{ - const std::string sql( - "UPDATE account" - " SET firstname = ?" - " WHERE id = ?" - ); - - exec(db_.instance(), sql, {name, id_}); -} - -/* - * sqlite_account::do_set_lastname - * ------------------------------------------------------------------ - */ -void sqlite_account::do_set_lastname(const std::string& name) -{ - const std::string sql( - "UPDATE account" - " SET lastname = ?" - " WHERE id = ?" - ); - - exec(db_.instance(), sql, {name, id_}); -} - -/* - * sqlite_account::sqlite_dao::get - * ------------------------------------------------------------------ - */ -std::unique_ptr<sqlite_account> sqlite_dao::get(const stmt_ptr& stmt) -{ - auto step = sqlite3_step(stmt.get()); - - switch (step) { - case SQLITE_DONE: - // No row, not found so just return an empty account. - return nullptr; - case SQLITE_ERROR: - case SQLITE_MISUSE: - throw std::runtime_error(sqlite3_errmsg(db_.instance())); - default: - break; - } - - auto ac = std::make_unique<sqlite_account>(to_string(stmt, 1), to_string(stmt, 2), db_); - - ac->id_ = to_int(stmt, 0); - ac->email_ = to_string(stmt, 3); - ac->firstname_ = to_string(stmt, 4); - ac->lastname_ = to_string(stmt, 5); - ac->characters_ = db_.sqlite_character_dao().characters_for_account(ac->id_); - - return ac; -} - -/* - * sqlite_account::sqlite_dao::find_by_login - * ------------------------------------------------------------------ - */ -std::unique_ptr<account> sqlite_dao::find_by_login(const std::string& login) -{ - const std::string sql( - "SELECT *" - " FROM account" - " WHERE login = ?" - ); - - return get(query(db_.instance(), sql, {login})); -} - -} // !server - -} // !db
--- a/libdb-sqlite/malikania/server/db/sqlite_account.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * sqlite_account.hpp -- database account object (SQLite implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_DB_SQLITE_ACCOUNT_HPP -#define MALIKANIA_DB_SQLITE_ACCOUNT_HPP - -/** - * \file sqlite_account.hpp - * \brief Database account object (SQLite implementation). - */ - -#include <malikania/server/db/account.hpp> - -#include "common.hpp" - -namespace mlk { - -namespace server { - -class sqlite_database; - -/** - * \brief Database account object (SQLite implementation). - */ -class sqlite_account : public account { -public: - class sqlite_dao; - -private: - sqlite_database& db_; - -protected: - /** - * \copydoc account::do_save - */ - void do_save() override; - - /** - * \copydoc account::do_remove - */ - void do_remove() override; - - /** - * \copydoc account::do_set_password - */ - void do_set_password(const std::string& password) override; - - /** - * \copydoc account::do_set_email - */ - void do_set_email(const std::string& email) override; - - /** - * \copydoc account::do_set_firstname - */ - void do_set_firstname(const std::string& name) override; - - /** - * \copydoc account::do_set_lastname - */ - void do_set_lastname(const std::string& name) override; - -public: - /** - * Create the sqlite account. - * - * \pre instance != nullptr - * \param login the login name - * \param password the password - * \param db the sqlite_database owner - */ - inline sqlite_account(std::string login, std::string password, sqlite_database& db) noexcept - : account(std::move(login), std::move(password)) - , db_(db) - { - } -}; - -/** - * \brief DAO for accounts (SQLite implementation). - */ -class sqlite_account::sqlite_dao : public account::dao { -private: - sqlite_database& db_; - - std::unique_ptr<sqlite_account> get(const stmt_ptr& stmt); - -protected: - /** - * \copydoc dao::find_by_login - */ - std::unique_ptr<account> find_by_login(const std::string& login) override; - -public: - /** - * Construct the DAO. - * - * \param db the sqlite_database owner - */ - inline sqlite_dao(sqlite_database& db) noexcept - : db_(db) - { - } -}; - -} // !server - -} // !mlk - -#endif // !MALIKANIA_DB_SQLITE_ACCOUNT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libdb-sqlite/malikania/server/db/sqlite_account_dao.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,136 @@ +/* + * sqlite_account_dao.cpp -- database account object (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "sqlite_database.hpp" + +namespace mlk { + +namespace server { + +void sqlite_account_dao::publish(account& ac) +{ + const std::string sql( + "INSERT INTO account(login, password, email, firstname, lastname)" + "VALUES (?, ?, ?, ?, ?)" + ); + + exec(db_.instance(), sql, { + ac.get_login(), + ac.get_password(), + ac.get_email(), + ac.get_firstname(), + ac.get_lastname() + }); + ac.set_id(sqlite3_last_insert_rowid(db_.instance())); +} + +void sqlite_account_dao::unpublish(const account& ac) +{ + const std::string sql( + "DELETE" + " FROM account" + " WHERE id = ?" + ); + + exec(db_.instance(), sql, {ac.get_id()}); +} + +void sqlite_account_dao::set_password(const account& ac, const std::string& password) +{ + const std::string sql( + "UPDATE account" + " SET password = ?" + " WHERE id = ?" + ); + + exec(db_.instance(), sql, {password, ac.get_id()}); +} + +void sqlite_account_dao::set_email(const account& ac, const std::string& email) +{ + const std::string sql( + "UPDATE account" + " SET email = ?" + " WHERE id = ?" + ); + + exec(db_.instance(), sql, {email, ac.get_id()}); +} + +void sqlite_account_dao::set_firstname(const account& ac, const std::string& name) +{ + const std::string sql( + "UPDATE account" + " SET firstname = ?" + " WHERE id = ?" + ); + + exec(db_.instance(), sql, {name, ac.get_id()}); +} + +void sqlite_account_dao::set_lastname(const account& ac, const std::string& name) +{ + const std::string sql( + "UPDATE account" + " SET lastname = ?" + " WHERE id = ?" + ); + + exec(db_.instance(), sql, {name, ac.get_id()}); +} + +boost::optional<account> sqlite_account_dao::get(const stmt_ptr& stmt) +{ + auto step = sqlite3_step(stmt.get()); + + switch (step) { + case SQLITE_DONE: + // No row, not found so just return an empty account. + return boost::none; + case SQLITE_ERROR: + case SQLITE_MISUSE: + throw std::runtime_error(sqlite3_errmsg(db_.instance())); + default: + break; + } + + account ac(db_, to_string(stmt, 1), to_string(stmt, 2)); + + ac.set_email(to_string(stmt, 3)); + ac.set_firstname(to_string(stmt, 4)); + ac.set_lastname(to_string(stmt, 5)); + ac.set_id(to_int(stmt, 0)); + ac.get_characters() = character_dao_.load(ac); + + return ac; +} + +boost::optional<account> sqlite_account_dao::find_by_login(const std::string& login) +{ + const std::string sql( + "SELECT *" + " FROM account" + " WHERE login = ?" + ); + + return get(query(db_.instance(), sql, {login})); +} + +} // !server + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libdb-sqlite/malikania/server/db/sqlite_account_dao.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,98 @@ +/* + * sqlite_account_dao.hpp -- database account object (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_DB_SQLITE_ACCOUNT_HPP +#define MALIKANIA_DB_SQLITE_ACCOUNT_HPP + +/** + * \file sqlite_account.hpp + * \brief Database account object (SQLite implementation). + */ + +#include <malikania/server/db/account.hpp> + +#include "common.hpp" + +namespace mlk { + +namespace server { + +class sqlite_database; +class sqlite_character_dao; + +class sqlite_account_dao : public account_dao { +private: + sqlite_database& db_; + sqlite_character_dao& character_dao_; + + boost::optional<account> get(const stmt_ptr&); + +public: + /** + * Constructor. + * + * \param db the database + * \param character_dao the character DAO for SQLite + */ + inline sqlite_account_dao(sqlite_database& db, sqlite_character_dao& character_dao) noexcept + : db_(db) + , character_dao_(character_dao) + { + } + + /** + * \copydoc account_dao::find_by_login + */ + boost::optional<account> find_by_login(const std::string& login) override; + + /** + * \copydoc account_dao::publish + */ + void publish(account& ac) override; + + /** + * \copydoc account_dao::unpublish + */ + void unpublish(const account& ac) override; + + /** + * \copydoc account_dao::set_password + */ + void set_password(const account& ac, const std::string& password) override; + + /** + * \copydoc account_dao::set_email + */ + void set_email(const account& ac, const std::string& email) override; + + /** + * \copydoc account_dao::set_firstname + */ + void set_firstname(const account& ac, const std::string& name) override; + + /** + * \copydoc account_dao::set_lastname + */ + void set_lastname(const account& ac, const std::string& name) override; +}; + +} // !server + +} // !mlk + +#endif // !MALIKANIA_DB_SQLITE_ACCOUNT_HPP
--- a/libdb-sqlite/malikania/server/db/sqlite_character.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * sqlite_character.cpp -- database character object (SQLite implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "sqlite_database.hpp" - -namespace mlk { - -namespace server { - -using sqlite_dao = sqlite_character::sqlite_dao; - -void sqlite_character::do_set_level(std::uint16_t level) -{ - const std::string sql( - "UPDATE character" - " SET level = ?" - " WHERE id = ?" - ); - - exec(db_.instance(), sql, {level, id_}); -} - -void sqlite_character::do_save(std::uint64_t account_id) -{ - const std::string sql( - "INSERT INTO character(" - " account_id," - " nickname," - " classname," - " level" - ") VALUES (?, ?, ?, ?)" - ); - - exec(db_.instance(), sql, {account_id, nickname_, classname_, level_}); -} - -void sqlite_character::do_remove() -{ - const std::string sql( - "DELETE FROM character WHERE id = ?" - ); - - exec(db_.instance(), sql, {id_}); -} - -std::unique_ptr<character> sqlite_dao::get(stmt_ptr& stmt) -{ - auto ch = std::make_unique<sqlite_character>(to_string(stmt, 2), to_string(stmt, 3), db_); - - ch->account_id_ = to_int(stmt, 1); - ch->level_ = to_int(stmt, 4); - ch->id_ = to_int(stmt, 0); - - return ch; -} - -character_list sqlite_dao::get_all(stmt_ptr stmt) -{ - character_list list; - - while (sqlite3_step(stmt.get()) == SQLITE_ROW) - list.push_back(get(stmt)); - - return list; -} - -character_list sqlite_dao::characters_for_account(std::uint64_t account_id) -{ - const std::string sql( - "SELECT *" - " FROM character" - " WHERE account_id = ?" - ); - - return get_all(query(db_.instance(), sql, {account_id})); -} - -} // !server - -} // !mlk
--- a/libdb-sqlite/malikania/server/db/sqlite_character.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -/* - * sqlite_character.hpp -- database character object (SQLite implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_DB_SQLITE_CHARACTER_HPP -#define MALIKANIA_DB_SQLITE_CHARACTER_HPP - -/** - * \file sqlite_character.hpp - * \brief Database character object (SQLite implementation). - */ - -#include <malikania/server/db/character.hpp> - -#include "common.hpp" - -namespace mlk { - -namespace server { - -class sqlite_database; - -/** - * \brief Database character object (SQLite implementation). - */ -class sqlite_character : public character { -private: - sqlite_database& db_; - -public: - class sqlite_dao; - -protected: - /** - * \copydoc character::do_set_level - */ - void do_set_level(std::uint16_t level) override; - - /** - * \copydoc character::do_save - */ - void do_save(std::uint64_t account_id) override; - - /** - * \copydoc character::do_remove - */ - void do_remove() override; - -public: - /** - * Construct the sqlite character. - * - * \pre instance != nullptr - * \param nickname the nickname - * \param classname the classname - * \param db the sqlite_database owner - */ - inline sqlite_character(std::string nickname, std::string classname, sqlite_database& db) noexcept - : character(std::move(nickname), std::move(classname)) - , db_(db) - { - } -}; - -/** - * \brief DAO for characters (SQLite implementation). - */ -class sqlite_character::sqlite_dao { -private: - sqlite_database& db_; - - std::unique_ptr<character> get(stmt_ptr& stmt); - - character_list get_all(stmt_ptr stmt); - -public: - /** - * Construct the DAO. - * - * \param db the sqlite_database owner - */ - inline sqlite_dao(sqlite_database& db) noexcept - : db_(db) - { - } - - /** - * Get the set of characters for the given account. - */ - character_list characters_for_account(std::uint64_t account_id); -}; - -} // !server - -} // !mlk - -#endif // !MALIKANIA_DB_SQLITE_CHARACTER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libdb-sqlite/malikania/server/db/sqlite_character_dao.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,93 @@ +/* + * sqlite_character_dao.cpp -- database character object (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "sqlite_database.hpp" + +namespace mlk { + +namespace server { + +character sqlite_character_dao::get(stmt_ptr& stmt) +{ + character ch(db_, to_string(stmt, 2), to_string(stmt, 3)); + + ch.set_level(to_int(stmt, 4)); + ch.set_id(to_int(stmt, 0)); + + return ch; +} + +void sqlite_character_dao::set_level(const character& ch, std::uint16_t level) +{ + const std::string sql( + "UPDATE character" + " SET level = ?" + " WHERE id = ?" + ); + + exec(db_.instance(), sql, {level, ch.get_id()}); +} + +void sqlite_character_dao::publish(character& ch, const account& parent) +{ + const std::string sql( + "INSERT INTO character(" + " account_id," + " nickname," + " classname," + " level" + ") VALUES (?, ?, ?, ?)" + ); + + exec(db_.instance(), sql, { + parent.get_id(), + ch.get_nickname(), + ch.get_classname(), + ch.get_level() + }); +} + +void sqlite_character_dao::unpublish(const character& ch) +{ + const std::string sql( + "DELETE FROM character WHERE id = ?" + ); + + exec(db_.instance(), sql, {ch.get_id()}); +} + +std::vector<character> sqlite_character_dao::load(const account& parent) +{ + const std::string sql( + "SELECT *" + " FROM character" + " WHERE account_id = ?" + ); + + stmt_ptr stmt = query(db_.instance(), sql, {parent.get_id()}); + std::vector<character> characters; + + while (sqlite3_step(stmt.get()) == SQLITE_ROW) + characters.push_back(get(stmt)); + + return characters; +} + +} // !server + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libdb-sqlite/malikania/server/db/sqlite_character_dao.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,86 @@ +/* + * sqlite_character_dao.hpp -- database character object (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_DB_SQLITE_CHARACTER_HPP +#define MALIKANIA_DB_SQLITE_CHARACTER_HPP + +/** + * \file sqlite_character.hpp + * \brief Database character object (SQLite implementation). + */ + +#include <malikania/server/db/character.hpp> + +#include "common.hpp" + +namespace mlk { + +namespace server { + +class account; +class sqlite_database; + +/** + * \brief Database character object (SQLite implementation). + */ +class sqlite_character_dao : public character_dao { +private: + sqlite_database& db_; + + character get(stmt_ptr&); + +public: + /** + * Constructor. + * + * \param db the SQLite database. + */ + inline sqlite_character_dao(sqlite_database& db) noexcept + : db_(db) + { + } + + /** + * Get the list of characters for this account. + * + * \param parent the parent account + * \return the list of characters + */ + std::vector<character> load(const account& parent); + + /** + * \copydoc character_dao::set_level + */ + void set_level(const character& ch, std::uint16_t level) override; + + /** + * \copydoc character_dao::publish + */ + void publish(character& ch, const account& parent) override; + + /** + * \copydoc character_dao::unpublish + */ + void unpublish(const character& ch) override; +}; + +} // !server + +} // !mlk + +#endif // !MALIKANIA_DB_SQLITE_CHARACTER_HPP
--- a/libdb-sqlite/malikania/server/db/sqlite_database.cpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libdb-sqlite/malikania/server/db/sqlite_database.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -1,6 +1,24 @@ +/* + * sqlite_database.cpp -- database access (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #include "sqlite_database.hpp" -#include "sqlite_account.hpp" -#include "sqlite_character.hpp" +#include "sqlite_account_dao.hpp" +#include "sqlite_character_dao.hpp" namespace mlk { @@ -66,21 +84,6 @@ exec(instance_.get(), init_spell); } -std::unique_ptr<account> sqlite_database::account_draft(std::string login, std::string password) -{ - return std::make_unique<sqlite_account>(std::move(login), std::move(password), *this); -} - -account::dao& sqlite_database::account_dao() -{ - return account_dao_; -} - -std::unique_ptr<character> sqlite_database::character_draft(std::string nickname, std::string classname) -{ - return std::make_unique<sqlite_character>(std::move(nickname), std::move(classname), *this); -} - } // !server } // !mlk
--- a/libdb-sqlite/malikania/server/db/sqlite_database.hpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libdb-sqlite/malikania/server/db/sqlite_database.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -1,3 +1,21 @@ +/* + * sqlite_database.hpp -- database access (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #ifndef MALIKANIA_DB_SQLITE_DATABASE_HPP #define MALIKANIA_DB_SQLITE_DATABASE_HPP @@ -5,8 +23,9 @@ #include <malikania/server/db/database.hpp> -#include "sqlite_account.hpp" -#include "sqlite_character.hpp" +#include "sqlite_account_dao.hpp" +#include "sqlite_character_dao.hpp" +#include "sqlite_spell_dao.hpp" namespace mlk { @@ -18,8 +37,9 @@ private: sqlite3_ptr instance_{nullptr, nullptr}; - sqlite_account::sqlite_dao account_dao_{*this}; - sqlite_character::sqlite_dao character_dao_{*this}; + sqlite_spell_dao spell_dao_{*this}; + sqlite_character_dao character_dao_{*this}; + sqlite_account_dao account_dao_{*this, character_dao_}; sqlite3_ptr open(const std::string&) const; @@ -42,34 +62,33 @@ } /** - * Get the real underlying sqlite_character::sqlite_dao. - * - * \return the character dao + * \copydoc database::init + */ + void init() override; + + /** + * \copydoc database::accounts */ - inline sqlite_character::sqlite_dao& sqlite_character_dao() noexcept + account_dao& accounts() override + { + return account_dao_; + } + + /** + * \copydoc database::characters + */ + character_dao& characters() override { return character_dao_; } /** - * \copydoc database::init - */ - void init() override; - - /** - * \copydoc database::account_draft + * \copydoc database::spells */ - std::unique_ptr<account> account_draft(std::string login, std::string password) override; - - /** - * \copydoc database::account_dao - */ - account::dao& account_dao() override; - - /** - * \copydoc database::character_draft - */ - std::unique_ptr<character> character_draft(std::string nickname, std::string classname) override; + spell_dao& spells() override + { + return spell_dao_; + } }; } // !server
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libdb-sqlite/malikania/server/db/sqlite_spell_dao.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,48 @@ +/* + * sqlite_spell_dao.cpp -- database spell object (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "sqlite_database.hpp" + +namespace mlk { + +namespace server { + +void sqlite_spell_dao::publish(const character& ch, spell& sp) +{ + // TODO: implement this. + (void)ch; + (void)sp; +} + +void sqlite_spell_dao::unpublish(const character& ch, const spell& sp) +{ + // TODO: implement this. + (void)ch; + (void)sp; +} + +void sqlite_spell_dao::set_level(const character& ch, std::uint8_t level) +{ + // TODO: implement this. + (void)ch; + (void)level; +} + +} // !server + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libdb-sqlite/malikania/server/db/sqlite_spell_dao.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,65 @@ +/* + * sqlite_spell_dao.hpp -- database spell object (SQLite implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_DB_SQLITE_SPELL_HPP +#define MALIKANIA_DB_SQLITE_SPELL_HPP + +#include <malikania/server/db/spell.hpp> + +namespace mlk { + +namespace server { + +class sqlite_database; + +class sqlite_spell_dao : public spell_dao { +private: + sqlite_database& db_; + +public: + /** + * Constructor. + * + * \param db the SQLite database. + */ + inline sqlite_spell_dao(sqlite_database& db) noexcept + : db_(db) + { + } + + /** + * \copydoc spell_dao::publish + */ + void publish(const character& ch, spell& sp) override; + + /** + * \copydoc spell_dao::unpublish + */ + void unpublish(const character& ch, const spell& sp) override; + + /** + * \copydoc spell_dao::set_level + */ + void set_level(const character& ch, std::uint8_t level) override; +}; + +} // !server + +} // !mlk + +#endif // !MALIKANIA_DB_SQLITE_SPELL_HPP
--- a/libserver-test/CMakeLists.txt Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver-test/CMakeLists.txt Sat Mar 03 17:34:12 2018 +0100 @@ -20,29 +20,24 @@ set( HEADERS - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_account.hpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_character.hpp + ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_account_dao.hpp + ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_character_dao.hpp + ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_spell_dao.hpp ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/database_fixture.hpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_account.hpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_character.hpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_database.hpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_spell.hpp ) set( SOURCES - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_account.cpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_character.cpp + ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_account_dao.cpp + ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_character_dao.cpp + ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/broken_spell_dao.cpp ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/database_fixture.cpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_account.cpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_character.cpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_database.cpp - ${libmlk-server-test_SOURCE_DIR}/malikania/server/db/test_spell.cpp ) malikania_define_library( TARGET libmlk-server-test SOURCES ${HEADERS} ${SOURCES} + FLAGS MALIKANIA_PRIVATE LIBRARIES libmlk-db-sqlite libmlk-server
--- a/libserver-test/malikania/server/db/broken_account.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * broken_account.cpp -- database account object (broken implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdexcept> - -#include "broken_account.hpp" - -namespace mlk { - -namespace server { - -void broken_account::do_save() -{ - if (!bool(allow_ & allow_flags::save)) - throw std::runtime_error("broken do_save"); - - id_ = 1; -} - -void broken_account::do_remove() -{ - if (!bool(allow_& allow_flags::remove)) - throw std::runtime_error("broken do_remove"); -} - -void broken_account::do_set_password(const std::string&) -{ - if (!bool(allow_ & allow_flags::set_password)) - throw std::runtime_error("broken do_set_password"); -} - -void broken_account::do_set_email(const std::string&) -{ - if (!bool(allow_ & allow_flags::set_email)) - throw std::runtime_error("broken do_set_email"); -} - -void broken_account::do_set_firstname(const std::string&) -{ - if (!bool(allow_ & allow_flags::set_firstname)) - throw std::runtime_error("broken do_set_firstname"); -} - -void broken_account::do_set_lastname(const std::string&) -{ - if (!bool(allow_ & allow_flags::set_lastname)) - throw std::runtime_error("broken do_set_lastname"); -} - -} // !server - -} // !mlk
--- a/libserver-test/malikania/server/db/broken_account.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* - * broken_account.hpp -- database account object (broken implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SERVER_BROKEN_ACCOUNT_HPP -#define MALIKANIA_SERVER_BROKEN_ACCOUNT_HPP - -/** - * \file broken_account.hpp - * \brief Database account object (broken implementation). - */ - -#include <malikania/server/db/account.hpp> - -namespace mlk { - -namespace server { - -/** - * \brief Database account object (broken implementation). - */ -class broken_account : public account { -public: - /** - * \brief Define which function should not be broken. - */ - enum class allow_flags { - none = 0, //!< everything is broken - save = (1 << 0), //!< allow do_save - remove = (1 << 1), //!< allow do_remove - set_password = (1 << 2), //!< allow do_set_password - set_email = (1 << 3), //!< allow do_set_email - set_firstname = (1 << 4), //!< allow do_set_firstname - set_lastname = (1 << 5) //!< allow do_set_lastname - }; - -private: - allow_flags allow_; - -protected: - /** - * \copydoc account::do_save - */ - void do_save() override; - - /** - * \copydoc account::do_remove - */ - void do_remove() override; - - /** - * \copydoc account::do_set_password - */ - void do_set_password(const std::string& password) override; - - /** - * \copydoc account::do_set_email - */ - void do_set_email(const std::string& email) override; - - /** - * \copydoc account::do_set_firstname - */ - void do_set_firstname(const std::string& name) override; - - /** - * \copydoc account::do_set_lastname - */ - void do_set_lastname(const std::string& name) override; - -public: - /** - * Construct a broken account. - * - * \param login the login - * \param password the password - * \param flags the flags for a less broken account - */ - inline broken_account(std::string login, - std::string password, - allow_flags flags = allow_flags::none) noexcept - : account(std::move(login), std::move(password)) - , allow_(flags) - { - } -}; - -/** - * \cond ENUM_HIDDEN_SYMBOLS - */ - -inline broken_account::allow_flags operator^(broken_account::allow_flags v1, broken_account::allow_flags v2) noexcept -{ - return static_cast<broken_account::allow_flags>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); -} - -inline broken_account::allow_flags operator&(broken_account::allow_flags v1, broken_account::allow_flags v2) noexcept -{ - return static_cast<broken_account::allow_flags>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); -} - -inline broken_account::allow_flags operator|(broken_account::allow_flags v1, broken_account::allow_flags v2) noexcept -{ - return static_cast<broken_account::allow_flags>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); -} - -inline broken_account::allow_flags operator~(broken_account::allow_flags v) noexcept -{ - return static_cast<broken_account::allow_flags>(~static_cast<unsigned>(v)); -} - -inline broken_account::allow_flags& operator|=(broken_account::allow_flags& v1, broken_account::allow_flags v2) noexcept -{ - return v1 = v1 | v2; -} - -inline broken_account::allow_flags& operator&=(broken_account::allow_flags& v1, broken_account::allow_flags v2) noexcept -{ - return v1 = v1 & v2; -} - -inline broken_account::allow_flags& operator^=(broken_account::allow_flags& v1, broken_account::allow_flags v2) noexcept -{ - return v1 = v1 ^ v2; -} - -/** - * \endcond - */ - -} // !server - -} // !mlk - -#endif // !MALIKANIA_SERVER_BROKEN_ACCOUNT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver-test/malikania/server/db/broken_account_dao.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,72 @@ +/* + * broken_account_dao.cpp -- database account object (broken implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdexcept> + +#include "broken_account_dao.hpp" + +namespace mlk { + +namespace server { + +boost::optional<account> broken_account_dao::find_by_login(const std::string&) +{ + throw std::runtime_error("broken find"); +} + +void broken_account_dao::publish(account& ac) +{ + if (!bool(allow_ & allow_flags::publish)) + throw std::runtime_error("broken publish"); + + ac.set_id(1U); +} + +void broken_account_dao::unpublish(const account&) +{ + if (!bool(allow_& allow_flags::unpublish)) + throw std::runtime_error("broken unpublish"); +} + +void broken_account_dao::set_password(const account&, const std::string&) +{ + if (!bool(allow_ & allow_flags::set_password)) + throw std::runtime_error("broken set_password"); +} + +void broken_account_dao::set_email(const account&, const std::string&) +{ + if (!bool(allow_ & allow_flags::set_email)) + throw std::runtime_error("broken set_email"); +} + +void broken_account_dao::set_firstname(const account&, const std::string&) +{ + if (!bool(allow_ & allow_flags::set_firstname)) + throw std::runtime_error("broken set_firstname"); +} + +void broken_account_dao::set_lastname(const account&, const std::string&) +{ + if (!bool(allow_ & allow_flags::set_lastname)) + throw std::runtime_error("broken set_lastname"); +} + +} // !server + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver-test/malikania/server/db/broken_account_dao.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,148 @@ +/* + * broken_account_dao.hpp -- database account object (broken implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_SERVER_BROKEN_ACCOUNT_HPP +#define MALIKANIA_SERVER_BROKEN_ACCOUNT_HPP + +/** + * \file broken_account.hpp + * \brief Database account object (broken implementation). + */ + +#include <malikania/server/db/account.hpp> + +namespace mlk { + +namespace server { + +/** + * \brief Database account object (broken implementation). + */ +class broken_account_dao : public account_dao { +public: + /** + * \brief Define which function should not be broken. + */ + enum class allow_flags { + none = 0, //!< everything is broken + publish = (1 << 0), //!< allow publish + unpublish = (1 << 1), //!< allow unpublish + set_password = (1 << 2), //!< allow set_password + set_email = (1 << 3), //!< allow set_email + set_firstname = (1 << 4), //!< allow set_firstname + set_lastname = (1 << 5) //!< allow set_lastname + }; + +private: + allow_flags allow_; + +public: + /** + * Set allow flags. + * + * \param flags the new flags + */ + inline void set_flags(allow_flags flags) noexcept + { + allow_ = flags; + } + + /** + * \copydoc account_dao::find_by_login + */ + boost::optional<account> find_by_login(const std::string& login) override; + + /** + * \copydoc account_dao::publish + */ + void publish(account& ac) override; + + /** + * \copydoc account_dao::unpublish + */ + void unpublish(const account& ac) override; + + /** + * \copydoc account_dao::set_password + */ + void set_password(const account& ac, const std::string& password) override; + + /** + * \copydoc account_dao::set_email + */ + void set_email(const account& ac, const std::string& email) override; + + /** + * \copydoc account_dao::set_firstname + */ + void set_firstname(const account& ac, const std::string& name) override; + + /** + * \copydoc account_dao::set_lastname + */ + void set_lastname(const account& ac, const std::string& name) override; +}; + +/** + * \cond ENUM_HIDDEN_SYMBOLS + */ + +inline broken_account_dao::allow_flags operator^(broken_account_dao::allow_flags v1, broken_account_dao::allow_flags v2) noexcept +{ + return static_cast<broken_account_dao::allow_flags>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); +} + +inline broken_account_dao::allow_flags operator&(broken_account_dao::allow_flags v1, broken_account_dao::allow_flags v2) noexcept +{ + return static_cast<broken_account_dao::allow_flags>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); +} + +inline broken_account_dao::allow_flags operator|(broken_account_dao::allow_flags v1, broken_account_dao::allow_flags v2) noexcept +{ + return static_cast<broken_account_dao::allow_flags>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); +} + +inline broken_account_dao::allow_flags operator~(broken_account_dao::allow_flags v) noexcept +{ + return static_cast<broken_account_dao::allow_flags>(~static_cast<unsigned>(v)); +} + +inline broken_account_dao::allow_flags& operator|=(broken_account_dao::allow_flags& v1, broken_account_dao::allow_flags v2) noexcept +{ + return v1 = v1 | v2; +} + +inline broken_account_dao::allow_flags& operator&=(broken_account_dao::allow_flags& v1, broken_account_dao::allow_flags v2) noexcept +{ + return v1 = v1 & v2; +} + +inline broken_account_dao::allow_flags& operator^=(broken_account_dao::allow_flags& v1, broken_account_dao::allow_flags v2) noexcept +{ + return v1 = v1 ^ v2; +} + +/** + * \endcond + */ + +} // !server + +} // !mlk + +#endif // !MALIKANIA_SERVER_BROKEN_ACCOUNT_HPP
--- a/libserver-test/malikania/server/db/broken_character.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * broken_character.cpp -- database character object (broken implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "broken_character.hpp" - -namespace mlk { - -namespace server { - -void broken_character::do_save(std::uint64_t) -{ - if (!bool(allow_ & allow_flags::save)) - throw std::runtime_error("broken do_save"); - - id_ = 1; -} - -void broken_character::do_remove() -{ - if (!bool(allow_ & allow_flags::remove)) - throw std::runtime_error("broken do_remove"); - - id_ = -1; -} - -void broken_character::do_set_level(std::uint16_t) -{ - if (!bool(allow_ & allow_flags::set_level)) - throw std::runtime_error("broken do_set_level"); -} - -} // !server - -} // !mlk
--- a/libserver-test/malikania/server/db/broken_character.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/* - * broken_character.hpp -- database character object (broken implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SERVER_BROKEN_CHARACTER_HPP -#define MALIKANIA_SERVER_BROKEN_CHARACTER_HPP - -/** - * \file broken_character.hpp - * \brief Database character object (broken implementation). - */ - -#include <malikania/server/db/character.hpp> - -namespace mlk { - -namespace server { - -/** - * \brief Database character object (broken implementation). - */ -class broken_character : public character { -public: - /** - * \brief Define which function should not be broken. - */ - enum class allow_flags : unsigned { - none = 0, //!< everything is broken - save = (1 << 0), //!< allow do_save - remove = (1 << 1), //!< allow do_remove - set_level = (1 << 2), //!< allow do_set_level - }; - -private: - allow_flags allow_; - -protected: - /** - * Called by account::add_character. - */ - void do_save(std::uint64_t account_id) override; - - /** - * Called by account::remove_character. - */ - void do_remove() override; - - /** - * Set the character level. - */ - void do_set_level(std::uint16_t level) override; - -public: - /** - * Construct a broken character. - * - * \param login the login - * \param password the password - * \param flags the flags for a less broken account - */ - inline broken_character(std::string nickname, - std::string classname, - allow_flags flags = allow_flags::none) noexcept - : character(std::move(nickname), std::move(classname)) - , allow_(flags) - { - } -}; - -/** - * \cond ENUM_HIDDEN_SYMBOLS - */ - -inline broken_character::allow_flags operator^(broken_character::allow_flags v1, broken_character::allow_flags v2) noexcept -{ - return static_cast<broken_character::allow_flags>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); -} - -inline broken_character::allow_flags operator&(broken_character::allow_flags v1, broken_character::allow_flags v2) noexcept -{ - return static_cast<broken_character::allow_flags>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); -} - -inline broken_character::allow_flags operator|(broken_character::allow_flags v1, broken_character::allow_flags v2) noexcept -{ - return static_cast<broken_character::allow_flags>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); -} - -inline broken_character::allow_flags operator~(broken_character::allow_flags v) noexcept -{ - return static_cast<broken_character::allow_flags>(~static_cast<unsigned>(v)); -} - -inline broken_character::allow_flags& operator|=(broken_character::allow_flags& v1, broken_character::allow_flags v2) noexcept -{ - return v1 = v1 | v2; -} - -inline broken_character::allow_flags& operator&=(broken_character::allow_flags& v1, broken_character::allow_flags v2) noexcept -{ - return v1 = v1 & v2; -} - -inline broken_character::allow_flags& operator^=(broken_character::allow_flags& v1, broken_character::allow_flags v2) noexcept -{ - return v1 = v1 ^ v2; -} - -/** - * \endcond - */ - -} // !server - -} // !mlk - -#endif // !MALIKANIA_SERVER_BROKEN_CHARACTER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver-test/malikania/server/db/broken_character_dao.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,49 @@ +/* + * broken_character_dao.cpp -- database character object (broken implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdexcept> + +#include "broken_character_dao.hpp" + +namespace mlk { + +namespace server { + +void broken_character_dao::publish(character& ch, const account&) +{ + if (!bool(allow_ & allow_flags::publish)) + throw std::runtime_error("broken publish"); + + ch.set_id(1U); +} + +void broken_character_dao::unpublish(const character&) +{ + if (!bool(allow_ & allow_flags::unpublish)) + throw std::runtime_error("broken unpublish"); +} + +void broken_character_dao::set_level(const character&, std::uint16_t) +{ + if (!bool(allow_ & allow_flags::set_level)) + throw std::runtime_error("broken set_level"); +} + +} // !server + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver-test/malikania/server/db/broken_character_dao.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,125 @@ +/* + * broken_character_dao.hpp -- database character object (broken implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_SERVER_BROKEN_CHARACTER_HPP +#define MALIKANIA_SERVER_BROKEN_CHARACTER_HPP + +/** + * \file broken_character.hpp + * \brief Database character object (broken implementation). + */ + +#include <malikania/server/db/character.hpp> + +namespace mlk { + +namespace server { + +/** + * \brief Database character object (broken implementation). + */ +class broken_character_dao : public character_dao { +public: + /** + * \brief Define which function should not be broken. + */ + enum class allow_flags : unsigned { + none = 0, //!< everything is broken + publish = (1 << 0), //!< allow publish + unpublish = (1 << 1), //!< allow unpublish + set_level = (1 << 2), //!< allow set_level + }; + +private: + allow_flags allow_; + +public: + /** + * Set allow flags. + * + * \param flags the new flags + */ + inline void set_flags(allow_flags flags) noexcept + { + allow_ = flags; + } + + /** + * \copydoc character_dao::set_level + */ + void set_level(const character& ch, std::uint16_t level) override; + + /** + * \copydoc character_dao::publish + */ + void publish(character& ch, const account& parent) override; + + /** + * \copydoc character_dao::unpublish + */ + void unpublish(const character& ch) override; +}; + +/** + * \cond ENUM_HIDDEN_SYMBOLS + */ + +inline broken_character_dao::allow_flags operator^(broken_character_dao::allow_flags v1, broken_character_dao::allow_flags v2) noexcept +{ + return static_cast<broken_character_dao::allow_flags>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); +} + +inline broken_character_dao::allow_flags operator&(broken_character_dao::allow_flags v1, broken_character_dao::allow_flags v2) noexcept +{ + return static_cast<broken_character_dao::allow_flags>(static_cast<unsigned>(v1) & static_cast<unsigned>(v2)); +} + +inline broken_character_dao::allow_flags operator|(broken_character_dao::allow_flags v1, broken_character_dao::allow_flags v2) noexcept +{ + return static_cast<broken_character_dao::allow_flags>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); +} + +inline broken_character_dao::allow_flags operator~(broken_character_dao::allow_flags v) noexcept +{ + return static_cast<broken_character_dao::allow_flags>(~static_cast<unsigned>(v)); +} + +inline broken_character_dao::allow_flags& operator|=(broken_character_dao::allow_flags& v1, broken_character_dao::allow_flags v2) noexcept +{ + return v1 = v1 | v2; +} + +inline broken_character_dao::allow_flags& operator&=(broken_character_dao::allow_flags& v1, broken_character_dao::allow_flags v2) noexcept +{ + return v1 = v1 & v2; +} + +inline broken_character_dao::allow_flags& operator^=(broken_character_dao::allow_flags& v1, broken_character_dao::allow_flags v2) noexcept +{ + return v1 = v1 ^ v2; +} + +/** + * \endcond + */ + +} // !server + +} // !mlk + +#endif // !MALIKANIA_SERVER_BROKEN_CHARACTER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver-test/malikania/server/db/broken_database.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,98 @@ +/* + * broken_database.hpp -- database access (broken implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_SERVER_BROKEN_DATABASE_HPP +#define MALIKANIA_SERVER_BROKEN_DATABASE_CPP + +#include <malikania/server/db/database.hpp> + +#include "broken_account_dao.hpp" +#include "broken_character_dao.hpp" +#include "broken_spell_dao.hpp" + +namespace mlk { + +namespace server { + +class broken_database : public database { +private: + broken_account_dao account_dao_; + broken_character_dao character_dao_; + broken_spell_dao spell_dao_; + +public: + /** + * Update allow flags on broken_account_dao. + * + * \param flags the new flags + */ + inline void set_account_flags(broken_account_dao::allow_flags flags) noexcept + { + account_dao_.set_flags(flags); + } + + /** + * Update allow flags on broken_character_dao. + * + * \param flags the new flags + */ + inline void set_character_flags(broken_character_dao::allow_flags flags) noexcept + { + character_dao_.set_flags(flags); + } + + /** + * Update allow flags on broken_spell_dao. + * + * \param flags the new flags + */ + inline void set_spell_flags(broken_spell_dao::allow_flags flags) noexcept + { + spell_dao_.set_flags(flags); + } + + /** + * \copydoc database::accounts + */ + account_dao& accounts() override + { + return account_dao_; + } + + /** + * \copydoc database::characters + */ + character_dao& characters() override + { + return character_dao_; + } + + /** + * \copydoc database::spells + */ + spell_dao& spells() override + { + return spell_dao_; + } +}; + +} // !server + +} // !mlk + +#endif // !MALIKANIA_SERVER_BROKEN_DATABASE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver-test/malikania/server/db/broken_spell_dao.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,45 @@ +/* + * broken_spell_dao.cpp -- database spell object (broken implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "broken_spell_dao.hpp" + +namespace mlk { + +namespace server { + +void broken_spell_dao::publish(const character& ch, spell& sp) +{ + (void)ch; + (void)sp; +} + +void broken_spell_dao::unpublish(const character& ch, const spell& sp) +{ + (void)ch; + (void)sp; +} + +void broken_spell_dao::set_level(const character& ch, std::uint8_t level) +{ + (void)ch; + (void)level; +} + +} // !server + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libserver-test/malikania/server/db/broken_spell_dao.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -0,0 +1,74 @@ +/* + * broken_spell_dao.hpp -- database spell object (broken implementation) + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_SERVER_BROKEN_SPELL_DAO_HPP +#define MALIKANIA_SERVER_BROKEN_SPELL_DAO_HPP + +#include <malikania/server/db/spell.hpp> + +namespace mlk { + +namespace server { + +class broken_spell_dao : public spell_dao { +public: + /** + * \brief Define which function should not be broken. + */ + enum class allow_flags : unsigned { + none = 0, //!< everything is broken + publish = (1 << 0), //!< allow publish + unpublish = (1 << 1), //!< allow unpublish + set_level = (1 << 2), //!< allow set_level + }; + +private: + allow_flags allow_; + +public: + /** + * Set allow flags. + * + * \param flags the new flags + */ + inline void set_flags(allow_flags flags) noexcept + { + allow_ = flags; + } + + /** + * \copydoc spell_dao::publish + */ + void publish(const character& ch, spell& sp) override; + + /** + * \copydoc spell_dao::unpublish + */ + void unpublish(const character& ch, const spell& sp) override; + + /** + * \copydoc spell_dao::set_level + */ + void set_level(const character& ch, std::uint8_t level) override; +}; + +} // !server + +} // !mlk + +#endif // !MALIKANIA_SERVER_BROKEN_SPELL_DAO_HPP
--- a/libserver-test/malikania/server/db/database_fixture.hpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver-test/malikania/server/db/database_fixture.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -23,7 +23,6 @@ #include <boost/mpl/list.hpp> -#include <malikania/server/db/test_database.hpp> #include <malikania/server/db/sqlite_database.hpp> namespace mlk { @@ -58,28 +57,10 @@ }; /** - * \brief Create a test database fixture. - */ -class test_fixture { -private: - test_database db_; - -public: - /** - * Access the database object. - */ - inline database& db() noexcept - { - return db_; - } -}; - -/** * \brief List to use with BOOST_AUTO_TEST_CASE_TEMPLATE */ using database_types = boost::mpl::list< - sqlite_fixture, - test_fixture + sqlite_fixture >; } // !server
--- a/libserver-test/malikania/server/db/test_account.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * test_account.cpp -- database account object (memory implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "test_database.hpp" - -namespace mlk { - -namespace server { - -using test_dao = test_account::test_dao; - -void test_account::do_save() -{ - assert(!db_.exists(*this)); - - id_ = db_.next_account_id(); - db_.dict(*this)[db_.sid(*this)] = serialize(); -} - -void test_account::do_remove() -{ - assert(db_.exists(*this)); - - db_.dict(*this).erase(db_.sid(*this)); -} - -void test_account::do_set_password(const std::string& password) -{ - assert(db_.exists(*this)); - - db_.ref(*this)["password"] = password; -} - -void test_account::do_set_email(const std::string& email) -{ - assert(db_.exists(*this)); - - db_.ref(*this)["email"] = email; -} - -void test_account::do_set_firstname(const std::string& name) -{ - assert(db_.exists(*this)); - - - db_.ref(*this)["firstname"] = name; -} - -void test_account::do_set_lastname(const std::string& name) -{ - assert(db_.exists(*this)); - - db_.ref(*this)["lastname"] = name; -} - -test_account::test_account(nlohmann::json json, test_database& db) - : test_account(json["login"], json["password"], db) -{ - id_ = json["id"]; - login_ = json["login"]; - password_ = json["password"]; - email_ = json["email"]; - firstname_ = json["firstname"]; - lastname_ = json["lastname"]; - - for (const auto& cdata : json["characters"]) - characters_.push_back(std::make_unique<test_character>(cdata, db_)); -} - -nlohmann::json test_account::serialize() const -{ - return { - { "id", id_ }, - { "login", login_ }, - { "password", password_ }, - { "email", email_ }, - { "firstname", firstname_ }, - { "lastname", lastname_ }, - { "characters", nlohmann::json::object() } - }; -} - -std::unique_ptr<account> test_dao::find_by_login(const std::string& login) -{ - for (const auto& v : db_.data()["accounts"]) - if (v["login"].get<std::string>() == login) - return std::make_unique<test_account>(v, db_); - - return nullptr; -} - -} // !server - -} // !mlk
--- a/libserver-test/malikania/server/db/test_account.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/* - * test_account.hpp -- database account object (memory implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SERVER_TEST_ACCOUNT_HPP -#define MALIKANIA_SERVER_TEST_ACCOUNT_HPP - -/** - * \file test_account.hpp - * \brief Database account object (memory implementation) - */ - -#include <unordered_map> - -#include <json.hpp> - -#include <malikania/server/db/account.hpp> - -#include "test_character.hpp" - -namespace mlk { - -namespace server { - -class test_database; - -/** - * \brief Database account object (memory implementation) - */ -class test_account : public account { -public: - class test_dao; - -private: - test_database& db_; - -public: - /** - * Parse the JSON as account. - * - * This also load recursively characters. - * - * \warning json input is not verified - * \param json the JSON input - * \param db the database - */ - test_account(nlohmann::json json, test_database& db); - - /** - * Construct a test_account. - * - * \param login the login - * \param password the password - * \param db the test_database - */ - inline test_account(std::string login, std::string password, test_database& db) noexcept - : account(std::move(login), std::move(password)) - , db_(db) - { - } - - /** - * Path where accounts are saved in JSON. - * - * \return the path as JSON pointer - */ - inline std::string path() const noexcept - { - return "/accounts"; - } - - /** - * Dump this account as json. - * - * \return the json - */ - nlohmann::json serialize() const; - - /** - * \copydoc account::do_save - */ - void do_save() override; - - /** - * \copydoc account::do_remove - */ - void do_remove() override; - - /** - * \copydoc account::do_set_password - */ - void do_set_password(const std::string& password) override; - - /** - * \copydoc account::do_set_email - */ - void do_set_email(const std::string& email) override; - - /** - * \copydoc account::do_set_firstname - */ - void do_set_firstname(const std::string& name) override; - - /** - * \copydoc account::do_set_lastname - */ - void do_set_lastname(const std::string& name) override; -}; - -/** - * \brief Account dao for test_account. - * - * This class saves accounts in memory, thus once deleted the no accounts are - * available anymore. - */ -class test_account::test_dao : public account::dao { -private: - test_database& db_; - -public: - /** - * Construct the dao, requires character_dao to load characters. - * - * \param db the test databasse - */ - inline test_dao(test_database& db) noexcept - : db_(db) - { - } - - /** - * \copydoc dao::find_by_login - */ - std::unique_ptr<account> find_by_login(const std::string& login) override; -}; - -} // !server - -} // !mlk - -#endif // !MALIKANIA_SERVER_TEST_ACCOUNT_HPP
--- a/libserver-test/malikania/server/db/test_character.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * test_character.cpp -- database account object (memory implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "test_database.hpp" - -namespace mlk { - -namespace server { - -using test_dao = test_character::test_dao; - -void test_character::do_save(std::uint64_t account_id) -{ - id_ = db_.next_character_id(); - account_id_ = account_id; - db_.dict(*this)[db_.sid(*this)] = serialize(); -} - -void test_character::do_remove() -{ - db_.dict(*this).erase(db_.sid(*this)); -} - -void test_character::do_set_level(std::uint16_t level) -{ - db_.ref(*this)["level"] = level; -} - -nlohmann::json test_character::serialize() const -{ - return { - { "id", id_ }, - { "account_id", account_id_ }, - { "nickname", nickname_ }, - { "classname", classname_ }, - { "level", level_ } - }; -} - -test_character::test_character(nlohmann::json json, test_database& db) - : test_character(json["nickname"], json["classname"], db) -{ - id_ = json["id"]; - account_id_ = json["account_id"]; - nickname_ = json["nickname"]; - classname_ = json["classname"]; - level_ = json["level"]; -} - -} // !server - -} // !mlk
--- a/libserver-test/malikania/server/db/test_character.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * test_character.hpp -- database account object (memory implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SERVER_TEST_CHARACTER_HPP -#define MALIKANIA_SERVER_TEST_CHARACTER_HPP - -/** - * \file test_account.hpp - * \brief Database account object (memory implementation) - */ - -#include <unordered_map> -#include <sstream> - -#include <json.hpp> - -#include <malikania/server/db/character.hpp> - -namespace mlk { - -namespace server { - -class test_database; - -/** - * \brief Database account object (memory implementation) - */ -class test_character : public character { -public: - class test_dao; - -private: - test_database& db_; - -protected: - /** - * \copydoc character::do_save - */ - void do_save(std::uint64_t account_id) override; - - /** - * \copydoc character::do_remove - */ - void do_remove() override; - - /** - * \copydoc character::do_set_level - */ - void do_set_level(std::uint16_t level) override; - -public: - /** - * Parse the JSON as character. - * - * This also load recursively spells. - * - * \warning json input is not verified - * \param json the JSON input - * \param db the database - */ - test_character(nlohmann::json json, test_database& db); - - /** - * Construct a test account. - * - * \param nickname the nickname - * \param classname the classname - * \param db reference to test_database - */ - inline test_character(std::string nickname, std::string classname, test_database& db) noexcept - : character(std::move(nickname), std::move(classname)) - , db_(db) - { - } - - /** - * Path where characters are saved in JSON. - * - * \return the path as JSON pointer - */ - inline std::string path() const - { - assert(account_id_ > 0); - - std::ostringstream oss; - - oss << "/accounts/" << account_id_; - oss << "/characters"; - - return oss.str(); - } - - /** - * Dump this account as json. - * - * \return the json - */ - nlohmann::json serialize() const; -}; - -} // !server - -} // !mlk - -#endif // !MALIKANIA_SERVER_TEST_CHARACTER_HPP
--- a/libserver-test/malikania/server/db/test_database.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * test_database.cpp -- database test (memory implementation) - * - * Copyright (c) 2013-2018 Alexis Dörr <nanahara@malikania.fr> - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "test_database.hpp" - -namespace mlk { - -namespace server { - -/* - * test_database::test_database - * ------------------------------------------------------------------ - * - * We can't use the in-class initialization because the JSON object will be - * constructed as an array. - */ -test_database::test_database() - : data_(nlohmann::json::value_t::object) -{ - data_["accounts"] = nlohmann::json::object(); -} - -std::unique_ptr<account> test_database::account_draft(std::string login, std::string password) -{ - return std::make_unique<test_account>(std::move(login), std::move(password), *this); -} - -account::dao& test_database::account_dao() -{ - return account_dao_; -} - -std::unique_ptr<character> test_database::character_draft(std::string nickname, std::string classname) -{ - return std::make_unique<test_character>(std::move(nickname), std::move(classname), *this); -} - -} // !server - -} // !mlk
--- a/libserver-test/malikania/server/db/test_database.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,217 +0,0 @@ -/* - * test_database.hpp -- database test (memory implementation) - * - * Copyright (c) 2013-2018 Alexis Dörr <nanahara@malikania.fr> - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SERVER_TEST_DATABASE_HPP -#define MALIKANIA_SERVER_TEST_DATABASE_HPP - -/** - * \file test_database.hpp - * \brief In memory database implementation for test purposes. - */ - -#include <malikania/server/db/database.hpp> - -#include <json.hpp> - -#include "test_account.hpp" -#include "test_character.hpp" -#include "test_spell.hpp" - -namespace mlk { - -namespace server { - -/** - * \brief In memory database implementation for test purposes. - */ -class test_database : public database { -private: - nlohmann::json data_; - test_spell::test_dao spell_dao_{*this}; - test_account::test_dao account_dao_{*this}; - std::uint64_t seq_account_id_{1}; - std::uint64_t seq_character_id_{1}; - -public: - /** - * Construct the database and initialize the JSON tree. - */ - test_database(); - - /** - * Get the next account id. - * - * \return the next id - */ - inline std::uint64_t next_account_id() noexcept - { - return seq_account_id_ ++; - } - - /** - * Get the next character id. - * - * \return the next character id - */ - inline std::uint64_t next_character_id() noexcept - { - return seq_character_id_ ++; - } - - /** - * Access the underlying data. - * - * \return the data - */ - inline const nlohmann::json& data() const noexcept - { - return data_; - } - - /** - * Overloaded function. - * - * \return the data - */ - inline nlohmann::json& data() noexcept - { - return data_; - } - - /** - * Get the real underlying test_dao type for accounts. - * - * \return the test_dao instance - */ - inline test_account::test_dao& test_account_dao() noexcept - { - return account_dao_; - } - - /** - * Get the real underlying test_dao type for spells. - * - * \return the test_spell::test_dao instance - */ - inline test_spell::test_dao& test_spell_dao() noexcept - { - return spell_dao_; - } - - /** - * \copydoc database::account_draft - */ - std::unique_ptr<account> account_draft(std::string login, std::string password) override; - - /** - * \copydoc database::account_dao - */ - account::dao& account_dao() override; - - /** - * \copydoc database::character_draft - */ - std::unique_ptr<character> character_draft(std::string nickname, std::string classname) override; - - /** - * Convert the model id into a string to be used as JSON keys. - * - * \return the string id - */ - inline std::string sid(const model& m) const noexcept - { - return std::to_string(m.id()); - } - - /** - * Overload that takes an id. - * - * \return the id - */ - inline std::string sid(std::uint64_t id) const noexcept - { - return std::to_string(id); - } - - /** - * Check if the specified object exists in JSON database. - * - * \param obj the object - * \return true if exists - */ - template <typename Object> - inline bool exists(const Object& obj) const noexcept - { - return data_[nlohmann::json::json_pointer(obj.path())].count(sid(obj)) > 0; - } - - /** - * Get the parent JSON object. - * - * \param obj the object - * \return the parent JSON object - */ - template <typename Object> - inline const nlohmann::json& dict(Object& obj) const noexcept - { - return data_[nlohmann::json::json_pointer(obj.path())]; - } - - /** - * Overloaded function. - * - * \param obj the object - * \return the parent JSON object - */ - template <typename Object> - inline nlohmann::json& dict(Object& obj) noexcept - { - return data_[nlohmann::json::json_pointer(obj.path())]; - } - - /** - * Get the reference to the object in JSON database. - * - * \param obj the object - * \return the reference to the object - */ - template <typename Object> - inline nlohmann::json& ref(Object& obj) noexcept - { - return data_[nlohmann::json::json_pointer(obj.path() + std::string("/") + sid(obj))]; - } - - /** - * Overloaded function - * - * \param obj the object - * \return the reference to the object - */ - template <typename Object> - inline const nlohmann::json& ref(const Object& obj) noexcept - { - return data_[nlohmann::json::json_pointer(obj.path() + std::string("/") + sid(obj))]; - } -}; - -} // !server - -} // !mlk - -#endif // !MALIKANIA_SERVER_TEST_DATABASE_HPP
--- a/libserver-test/malikania/server/db/test_spell.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -#include "test_database.hpp" - -namespace mlk { - -namespace server { - -using test_dao = test_spell::test_dao; - -void test_spell::do_save(std::uint64_t character_id) -{ - character_id_ = character_id; -} - -void test_spell::do_remove() -{ -} - -void test_spell::do_set_level(std::uint8_t) -{ -} - -nlohmann::json test_spell::serialize() const -{ - return { - { "id", id_ }, - { "character_id", character_id_ }, - { "classname", classname_ }, - { "level", level_ } - }; -} - -void test_spell::unserialize(const nlohmann::json& json) -{ - id_ = json["id"]; - character_id_ = json["character_id"]; - classname_ = json["classname"]; - level_ = json["level"]; -} - -spell_list test_dao::spells_for_charater(std::uint64_t character_id) -{ -#if 0 - spell_list list; - - for (const auto& pair : spells_) { - if (pair.second["character_id"].get<int>() == character_id) { - auto s = std::make_unique<test_spell>(pair.second["classname"], db_); - - s->unserialize(pair.second); - list.push_back(std::move(s)); - } - } - - return list; -#endif - spell_list list; - - (void)character_id; - - return list; -} - -void test_dao::remove_all(std::uint64_t character_id) -{ -#if 0 - for (auto it = spells_.begin(); it != spells_.end(); ) { - if (it->second["character_id"].get<int>() == character_id) - it = spells_.erase(it); - else - it++; - } -#endif - (void)character_id; -} - -} // !server - -} // !mlk
--- a/libserver-test/malikania/server/db/test_spell.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * test_spell.hpp -- database spell object (memory implementation) - * - * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SERVER_TEST_SPELL_HPP -#define MALIKANIA_SERVER_TEST_SPELL_HPP - -/** - * \file test_spell.hpp - * \brief Database spell object (memory implementation). - */ - -#include <unordered_map> - -#include <malikania/server/db/spell.hpp> - -#include <json.hpp> - -namespace mlk { - -namespace server { - -class test_database; - -/** - * \brief Database spell object (memory implementation). - */ -class test_spell : public spell { -public: - class test_dao; - -protected: - void do_save(std::uint64_t character_id) override; - void do_remove() override; - void do_set_level(std::uint8_t level) override; - -public: - inline test_spell(std::string classname, test_database&) noexcept - : spell(std::move(classname)) - { - } - - /** - * Dump this character as json. - * - * \return the json - */ - nlohmann::json serialize() const; - - /** - * Fill this character with json input. - * - * \warning json input must be valid, no checks are performed - * \param input the json input - */ - void unserialize(const nlohmann::json& json); -}; - -class test_spell::test_dao { -public: - inline test_dao(test_database&) noexcept - { - } - - /** - * Get the set of spells for the given character. - */ - spell_list spells_for_charater(std::uint64_t character_id); - - /** - * Remove all characters for the specified character. - * - * \param character_id the character id - */ - void remove_all(std::uint64_t character_id); -}; - -} // !server - -} // !mlk - -#endif // !MALIKANIA_SERVER_TEST_SPELL_HPP
--- a/libserver/malikania/server/db/account.cpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/account.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -23,55 +23,90 @@ namespace server { -/* - * account::add_character - * ------------------------------------------------------------------ - */ -std::unique_ptr<character>& account::add_character(std::unique_ptr<character> ch) +void account::set_password(std::string password) { - assert(is_published()); - assert(ch && ch->is_draft()); + assert(!password.empty()); + + if (is_published() && password_ != password) + db_.accounts().set_password(*this, password); + + password_ = std::move(password); +} - ch->do_save(id_); - characters_.push_back(std::move(ch)); +void account::set_email(std::string email) +{ + assert(!email.empty()); - return characters_.back(); + if (is_published() && email_ != email) + db_.accounts().set_email(*this, email); + + email_ = std::move(email); } -/* - * account::remove_character - * ------------------------------------------------------------------ - */ -void account::remove_character(std::unique_ptr<character>& ch) +void account::set_firstname(std::string name) +{ + if (is_published() && firstname_ != name) + db_.accounts().set_firstname(*this, name); + + firstname_ = std::move(name); +} + +void account::set_lastname(std::string name) { + if (is_published() && lastname_ != name) + db_.accounts().set_lastname(*this, name); + + lastname_ = std::move(name); +} + +void account::add(character ch) +{ + assert(is_published() && ch.is_draft()); + + db_.characters().publish(ch, *this); + characters_.push_back(std::move(ch)); +} + +void account::remove(std::vector<character>::iterator it) +{ + // TODO: assert it is in vector. assert(is_published()); - assert(ch && ch->is_published()); - auto it = std::find(characters_.begin(), characters_.end(), ch); - - if (it == characters_.end()) - return; - - ch->do_remove(); - ch = nullptr; + db_.characters().unpublish(*it); characters_.erase(it); } -/* - * account::dao::authenticate - * ------------------------------------------------------------------ - */ -std::unique_ptr<account> account::dao::authenticate(const std::string& login, - const std::string& password) +void account::save() +{ + if (is_draft()) + db_.accounts().publish(*this); + + assert(is_published()); +} + +void account::remove() +{ + if (is_published()) + db_.accounts().unpublish(*this); + + id_ = 0U; + characters_.clear(); + + assert(is_draft()); +} + +boost::optional<account> account_dao::authenticate(const std::string& login, + const std::string& password) { auto ac = find_by_login(login); - if (!ac || ac->password() != password) - return nullptr; + if (!ac || ac->get_password() != password) + return boost::none; return ac; } + } // !server } // !mlk
--- a/libserver/malikania/server/db/account.hpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/account.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -24,7 +24,7 @@ * \brief Database account object. */ -#include <algorithm> +#include <boost/optional.hpp> #include "model.hpp" #include "character.hpp" @@ -37,16 +37,203 @@ * \brief Database account object. */ class account : public model { -public: - class dao; - protected: std::string login_; //!< unique login (not null) std::string password_; //!< password stored as-is std::string email_; //!< raw email std::string firstname_; //!< optional first name std::string lastname_; //!< optional last name - character_list characters_; //!< list of characters + std::vector<character> characters_; //!< list of characters + +public: + /** + * Create a draft account. + * + * \pre !login.empty() + * \pre !password.empty() + * \param login the login name + * \param password the password + * \warning the password is saved as-is and **must** be hashed by the caller. + */ + inline account(database& db, std::string login, std::string password) noexcept + : model(db) + , login_(std::move(login)) + , password_(std::move(password)) + { + assert(!login_.empty()); + assert(!password_.empty()); + } + + /** + * Get the account login. + * + * \return the login + */ + inline const std::string& get_login() const noexcept + { + return login_; + } + + /** + * Get the password. + * + * \note the password is returned as-is + * \return the password + */ + inline const std::string& get_password() const noexcept + { + return password_; + } + + /** + * Set the password. + * + * \pre !password.empty() + * \warning the password is saved as-is and **must** be hashed by the caller. + */ + void set_password(std::string password); + + /** + * Get the account email. + * + * \return the email + */ + inline const std::string& get_email() const noexcept + { + return email_; + } + + /** + * Set the account email. + * + * \pre !email.empty() + * \param email the new email + */ + void set_email(std::string email); + + /** + * Get the account first name. + * + * \return the name + */ + inline const std::string& get_firstname() const noexcept + { + return firstname_; + } + + /** + * Set the account firstname. + * + * \param name the new name + */ + void set_firstname(std::string name); + + /** + * Get the account last name. + * + * \return the name + */ + inline const std::string& get_lastname() const noexcept + { + return lastname_; + } + + /** + * Set the account last name. + * + * \param name the new name + */ + void set_lastname(std::string name); + + /** + * Get the caracter list. + * + * \return the associated characters. + */ + inline const std::vector<character>& get_characters() const noexcept + { + return characters_; + } + +#if defined(MALIKANIA_PRIVATE) + /** + * Overloaded function. + * + * This function is only available if MALIKANIA_PRIVATE is defined as it is + * not a end user function but is required to implement new database + * backends. + * + * \warning only use this function in database backends + * \param characters the list of characters + */ + inline std::vector<character>& get_characters() noexcept + { + return characters_; + } +#endif // !MALIKANIA_PRIVATE + + /** + * Add the character to the account. + * + * Account takes ownership of character. + * + * \pre ch.is_draft() + * \param ch the character + * \post ch.is_published() + */ + void add(character ch); + + /** + * Remove the character from the account. + * + * \pre it is in the the account character list + * \param ch the character + * \post ch == nullptr + */ + void remove(std::vector<character>::iterator it); + + /** + * Save the account, does nothing if is_published(). + * + * \throw std::exception on errors + * \post is_published() + */ + void save(); + + /** + * Destroy the account. + * + * The account will contains no characters anymore. + * + * \throw std::exception on errors + * \post is_draft() + */ + void remove(); +}; + +/** + * \brief Account DAO. + */ +class account_dao { +public: + /** + * Authenticate the user. + * + * \param login the login + * \param password the password + * \return the account or null if does not exist + */ + boost::optional<account> authenticate(const std::string& login, + const std::string& password); + + /** + * Find an account by login. + * + * \param login the login name + * \return the account or null if not found + * \throw exception on other errors + */ + virtual boost::optional<account> find_by_login(const std::string& login) = 0; /** * Save the account. @@ -60,7 +247,7 @@ * \note called from account::save * \throw std::exception if the operation could not succeed */ - virtual void do_save() = 0; + virtual void publish(account& ac) = 0; /** * Remove the account. @@ -72,7 +259,7 @@ * \note called from account::remove * \throw std::exception if the operation could not succeed */ - virtual void do_remove() = 0; + virtual void unpublish(const account& ac) = 0; /** * Update the account password in database. @@ -83,7 +270,7 @@ * \note called from set_password helper * \throw std::exception if the operation could not succeed */ - virtual void do_set_password(const std::string& password) = 0; + virtual void set_password(const account& ac, const std::string& password) = 0; /** * Update the account email in database. @@ -94,7 +281,7 @@ * \note called from set_email helper * \throw std::exception if the operation could not succeed */ - virtual void do_set_email(const std::string& email) = 0; + virtual void set_email(const account& ac, const std::string& email) = 0; /** * Update the account firstname in database. @@ -105,7 +292,7 @@ * \note called from set_firstname helper * \throw std::exception if the operation could not succeed */ - virtual void do_set_firstname(const std::string& name) = 0; + virtual void set_firstname(const account& ac, const std::string& name) = 0; /** * Update the account lastname in database. @@ -116,244 +303,7 @@ * \note called from set_lastname helper * \throw std::exception if the operation could not succeed */ - virtual void do_set_lastname(const std::string& name) = 0; - - /** - * Create a draft account. - * - * \pre !login.empty() - * \pre !password.empty() - * \param login the login name - * \param password the password - * \warning the password is saved as-is and **must** be hashed by the caller. - */ - inline account(std::string login, std::string password) noexcept - : login_(std::move(login)) - , password_(std::move(password)) - { - assert(!login_.empty()); - assert(!password_.empty()); - } - -public: - /** - * Get the account login. - * - * \return the login - */ - inline const std::string& login() const noexcept - { - return login_; - } - - /** - * Get the password. - * - * \note the password is returned as-is - * \return the password - */ - inline const std::string& password() const noexcept - { - return password_; - } - - /** - * Set the password. - * - * \pre !password.empty() - * \warning the password is saved as-is and **must** be hashed by the caller. - */ - inline void set_password(std::string password) - { - assert(!password.empty()); - - if (is_published() && password_ != password) - do_set_password(password); - - password_ = std::move(password); - } - - /** - * Get the account email. - * - * \return the email - */ - inline const std::string& email() const noexcept - { - return email_; - } - - /** - * Set the account email. - * - * \pre !email.empty() - * \param email the new email - */ - inline void set_email(std::string email) - { - assert(!email.empty()); - - if (is_published() && email_ != email) - do_set_email(email); - - email_ = std::move(email); - } - - /** - * Get the account first name. - * - * \return the name - */ - inline const std::string& firstname() const noexcept - { - return firstname_; - } - - /** - * Set the account firstname. - * - * \param name the new name - */ - inline void set_firstname(std::string name) - { - if (is_published() && firstname_ != name) - do_set_firstname(name); - - firstname_ = std::move(name); - } - - /** - * Get the account last name. - * - * \return the name - */ - inline const std::string& lastname() const noexcept - { - return lastname_; - } - - /** - * Set the account last name. - * - * \param name the new name - */ - inline void set_lastname(std::string name) - { - if (is_published() && lastname_ != name) - do_set_lastname(name); - - lastname_ = std::move(name); - } - - /** - * Get the caracter set. - * - * \return the associated characters. - */ - inline const character_list& characters() const noexcept - { - return characters_; - } - - /** - * Add the character to the account. - * - * Account takes ownership of character. - * - * \pre ch->is_draft() - * \param ch the character - * \return the attached character - * \post ch->is_published() - */ - std::unique_ptr<character>& add_character(std::unique_ptr<character> ch); - - /** - * Find a character by a predicate. - * - * The predicate must be the same as one use in std::find_if, the unique - * value given as argument is the const std::unique_ptr<character>&. - * - * \param pred the unary predicate - * \return the character or null if not found. - */ - template <typename Predicate> - inline std::unique_ptr<character>& find_character(Predicate&& pred) noexcept - { - static std::unique_ptr<character> none; - - auto it = std::find_if(characters_.begin(), characters_.end(), std::forward<Predicate>(pred)); - - if (it != characters_.end()) - return *it; - - return none; - } - - /** - * Remove the character from the account. - * - * \param ch the character - * \post ch == nullptr - */ - void remove_character(std::unique_ptr<character>& ch); - - /** - * Save the account, does nothing if is_published(). - * - * \throw std::exception on errors - * \post is_published() - */ - inline void save() - { - if (is_draft()) - do_save(); - - assert(is_published()); - } - - /** - * Destroy the account. - * - * The account will contains no characters anymore. - * - * \throw std::exception on errors - * \post is_draft() - */ - inline void remove() - { - if (is_published()) - do_remove(); - - id_ = -1; - characters_.clear(); - - assert(is_draft()); - } -}; - -/** - * \brief DAO for accounts. - */ -class account::dao { -public: - /** - * Find an account by login. - * - * \param login the login name - * \return the account or null if not found - * \throw exception on other errors - */ - virtual std::unique_ptr<account> find_by_login(const std::string& login) = 0; - - /** - * Authenticate the user. - * - * \param login the login - * \param password the password - * \return the account or null if does not exist - */ - std::unique_ptr<account> authenticate(const std::string& login, - const std::string& password); + virtual void set_lastname(const account& ac, const std::string& name) = 0; }; } // !server
--- a/libserver/malikania/server/db/character.cpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/character.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -17,42 +17,33 @@ */ #include "character.hpp" +#include "database.hpp" namespace mlk { namespace server { -/* - * character::add_spell - * ------------------------------------------------------------------ - */ -std::unique_ptr<spell>& character::add_spell(std::unique_ptr<spell> sp) +void character::set_level(std::uint16_t level) { - assert(is_published()); - assert(sp && sp->is_draft()); + if (is_published() && level_ != level) + db_.characters().set_level(*this, level); - sp->do_save(id_); - spells_.push_back(std::move(sp)); - - return spells_.back(); + level_ = level; } -/* - * character::remove_spell - * ------------------------------------------------------------------ - */ -void character::remove_spell(std::unique_ptr<spell>& sp) +void character::add(spell sp) +{ + assert(is_published() && sp.is_draft()); + + db_.spells().publish(*this, sp); + spells_.push_back(std::move(sp)); +} + +void character::remove(std::vector<spell>::iterator it) { assert(is_published()); - assert(sp && sp->is_published()); - auto it = std::find(spells_.begin(), spells_.end(), sp); - - if (it == spells_.end()) - return; - - sp->do_remove(); - sp = nullptr; + db_.spells().unpublish(*this, *it); spells_.erase(it); }
--- a/libserver/malikania/server/db/character.hpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/character.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -24,7 +24,7 @@ * \brief Database character object. */ -#include <algorithm> +#include <vector> #include "model.hpp" #include "spell.hpp" @@ -33,19 +33,128 @@ namespace server { +class account; + /* * \brief Database character object. */ class character : public model { -private: - friend class account; - protected: - std::uint64_t account_id_{0U}; //!< parent account std::string nickname_; //!< nickname (non null) std::string classname_; //!< class type to instanciate std::uint16_t level_{1}; //!< character level - spell_list spells_; //!< list of spells + std::vector<spell> spells_; //!< list of spells + +public: + /** + * Construct a character, no database is modified yet. + * + * \pre !nickname.empty() + * \pre !classname.empty() + * \param nickname the nickname + * \param classname the classname + */ + inline character(database& db, std::string nickname, std::string classname) noexcept + : model(db) + , nickname_(std::move(nickname)) + , classname_(std::move(classname)) + { + assert(!nickname_.empty()); + assert(!classname_.empty()); + } + + /** + * Get the character nickname. + * + * \return the name + */ + inline const std::string& get_nickname() const noexcept + { + return nickname_; + } + + /** + * Get the character class name. + * + * \return the class name + */ + inline const std::string& get_classname() const noexcept + { + return classname_; + } + + /** + * Get the list of spells. + * + * \return the spells + */ + inline const std::vector<spell>& get_spells() const noexcept + { + return spells_; + } + +#if defined(MALIKANIA_PRIVATE) + /** + * Get the list of spells. + * + * \return the spells + */ + inline std::vector<spell>& get_spells() noexcept + { + return spells_; + } +#endif // !MALIKANIA_PRIVATE + + /** + * Get the account level. + * + * \return the level + */ + inline std::uint16_t get_level() const noexcept + { + return level_; + } + + /** + * Set the account level. + * + * \param level the level + */ + void set_level(std::uint16_t level); + + /** + * Add a spell. + * + * Character takes ownership of spell. + * + * \pre sp.is_draft() + * \param sp the spell (moved) + */ + void add(spell sp); + + /** + * Remove the spell from the character. + * + * \pre it must be valid + * \param it the spell iterator + */ + void remove(std::vector<spell>::iterator it); +}; + +/** + * \brief Character DAO. + */ +class character_dao { +public: + /** + * Default constructor. + */ + character_dao() = default; + + /** + * Virtual destructor defaulted. + */ + virtual ~character_dao() = default; /** * Save this character. @@ -55,11 +164,11 @@ * * Then it will be added into account.characters_ variable. * - * \param account_id the parent account - * \note called by account::add_character. + * \param account the parent account + * \param ch this character * \throw std::exception if the operation could not succeed */ - virtual void do_save(std::uint64_t account_id) = 0; + virtual void publish(character& ch, const account& account) = 0; /** * Remove this character. @@ -67,9 +176,9 @@ * The implementation must remove the character from the database and update * id, account_id member variables. * - * \note called by account::remove_character. + * \param ch this character */ - virtual void do_remove() = 0; + virtual void unpublish(const character& ch) = 0; /** * Update the character level in database. @@ -77,106 +186,14 @@ * Only called when the level needs to be changed, the implementation does * not need to update level_ field. * - * \note called from set_level helper + * \param ch the character + * \param level the new level + * \note called from character::set_level helper * \throw std::exception if the operation could not succeed */ - virtual void do_set_level(std::uint16_t level) = 0; - - /** - * Construct a character, no database is modified yet. - * - * \pre !nickname.empty() - * \pre !classname.empty() - * \param nickname the nickname - * \param classname the classname - */ - inline character(std::string nickname, std::string classname) - : nickname_(std::move(nickname)) - , classname_(std::move(classname)) - { - assert(!nickname_.empty()); - assert(!classname_.empty()); - } - -public: - /** - * Get the character nickname. - * - * \return the name - */ - inline const std::string& nickname() const noexcept - { - return nickname_; - } - - /** - * Get the character class name. - * - * \return the class name - */ - inline const std::string& classname() const noexcept - { - return classname_; - } - - /** - * Get the account level. - * - * \return the level - */ - inline std::uint16_t level() const noexcept - { - return level_; - } - - /** - * Get the set of spells. - * - * \return the spells - */ - inline const spell_list& spells() const noexcept - { - return spells_; - } - - /** - * Add a spell. - * - * Character takes ownership of spell. - * - * \pre sp->is_draft() - * \param sp the spell - * \return the attached spell - */ - std::unique_ptr<spell>& add_spell(std::unique_ptr<spell> sp); - - /** - * Remove the spell from the character. - * - * \param sp the spell - * \post sp == nullptr - */ - void remove_spell(std::unique_ptr<spell>& sp); - - /** - * Set the account level. - * - * \param level the level - */ - inline void set_level(std::uint16_t level) - { - if (is_published() && level_ != level) - do_set_level(level); - - level_ = level; - } + virtual void set_level(const character& ch, std::uint16_t level) = 0; }; -/** - * Type for storing characters. - */ -using character_list = std::vector<std::unique_ptr<character>>; - } // !server } // !mlk
--- a/libserver/malikania/server/db/database.hpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/database.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -24,14 +24,14 @@ * \brief Abstract database interface. */ -#include "account.hpp" -#include "character.hpp" -#include "spell.hpp" - namespace mlk { namespace server { +class account_dao; +class character_dao; +class spell_dao; + /** * \brief Abstract database interface. */ @@ -55,32 +55,15 @@ } /** - * Create a draft account. - * - * \param login the login name - * \param password the password - * \return a draft account - * \post value->is_draft() - * \see account::account - */ - virtual std::unique_ptr<account> account_draft(std::string login, std::string password) = 0; - - /** * Create the account dao. * * \return the account dao */ - virtual account::dao& account_dao() = 0; + virtual account_dao& accounts() = 0; - /** - * Create a draft character. - * - * \param nickname the character nickname - * \param classname the character class type - * \return the draft character - * \post value->is_draft() - */ - virtual std::unique_ptr<character> character_draft(std::string nickname, std::string classname) = 0; + virtual character_dao& characters() = 0; + + virtual spell_dao& spells() = 0; }; } // !server
--- a/libserver/malikania/server/db/model.hpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/model.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -31,6 +31,8 @@ namespace server { +class database; + /** * \brief Abstract database object. */ @@ -39,17 +41,30 @@ model(const model&) = delete; model& operator=(const model&) = delete; - model(model&&) = delete; - model& operator=(model&&) = delete; - protected: + database& db_; //!< database object std::uint64_t id_{0U}; //!< object id public: /** * Default constructor. */ - model() noexcept = default; + inline model(database& db) noexcept + : db_(db) + { + } + + /** + * Move constructor. + * + * \param other the original value (id resets to 0) + */ + inline model(model&& other) noexcept + : db_(other.db_) + , id_(other.id_) + { + other.id_ = 0U; + } /** * Virtual destructor defaulted. @@ -61,11 +76,28 @@ * * \return the id */ - inline std::uint64_t id() const noexcept + inline std::uint64_t get_id() const noexcept { return id_; } +#if defined(MALIKANIA_PRIVATE) + /** + * Set the internal id. + * + * This function is only available if MALIKANIA_PRIVATE is defined as it is + * not a end user function but is required to implement new database + * backends. + * + * \warning only use this function in database backends + * \param id the new id + */ + inline void set_id(std::uint64_t id) noexcept + { + id_ = id; + } +#endif + /** * Tells if the object is not persistent. * @@ -85,6 +117,20 @@ { return id_ > 0U; } + + /** + * Move operator. + * + * \param other the original value (id resets to 0) + * \return *this + */ + inline model& operator=(model&& other) noexcept + { + id_ = other.id_; + other.id_ = 0U; + + return *this; + } }; } // !server
--- a/libserver/malikania/server/db/spell.cpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/spell.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -24,6 +24,14 @@ namespace server { +void spell::set_level(std::uint8_t level) +{ + if (is_published() && level_ != level) + db_.spells().set_level(level); + + level_ = level; +} + } // !server } // !mlk
--- a/libserver/malikania/server/db/spell.hpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/db/spell.hpp Sat Mar 03 17:34:12 2018 +0100 @@ -24,77 +24,38 @@ * \brief Database spell object. */ -#include <memory> #include <string> -#include <vector> #include "model.hpp" namespace mlk { -/** - * \brief Database spell object. - */ namespace server { +class character; + /** * \brief Describe a spell. */ class spell : public model { -private: - friend class character; - protected: - std::uint64_t character_id_{0U}; //!< parent character std::string classname_; //!< class type to instanciate std::uint8_t level_{1}; //!< spell level - /** - * Save this spell. - * - * The implementation must save the spell and update id, character_id - * member variables. - * - * Then it will be added into character.spells_ variable. - * - * \note called by character::add_spell. - */ - virtual void do_save(std::uint64_t character_id) = 0; - - /** - * Remove this spell. - * - * The implementation must remove the spell from the database and update - * id, character_id member variables. - * - * \note called by character::remove_spell - */ - virtual void do_remove() = 0; - - /** - * Update the spell level in database. - * - * Only called when the level needs to be changed, the implementation does - * not need to update level_ field. - * - * \note called from set_level helper - * \throw std::exception if the operation could not succeed - */ - virtual void do_set_level(std::uint8_t level) = 0; - +public: /** * Constructor. * * \pre !classname.empty() * \param classname the class name */ - inline spell(std::string classname) - : classname_(std::move(classname)) + inline spell(database& db, std::string classname) + : model(db) + , classname_(std::move(classname)) { assert(!classname_.empty()); } -public: /** * Get the level. * @@ -110,19 +71,53 @@ * * \param level the level */ - inline void set_level(std::uint8_t level) - { - if (is_published() && level_ != level) - do_set_level(level); - - level_ = level; - } + void set_level(std::uint8_t level); }; /** - * Type for storing spells. + * \brief Character DAO. */ -using spell_list = std::vector<std::unique_ptr<spell>>; +class spell_dao { +public: + /** + * Default constructor. + */ + spell_dao() = default; + + /** + * Virtual destructor defaulted. + */ + virtual ~spell_dao() = default; + + /** + * Save this spell. + * + * The implementation must save the spell and update id, character_id + * member variables. + * + * Then it will be added into character.spells_ variable. + */ + virtual void publish(const character& ch, spell& sp) = 0; + + /** + * Remove this spell. + * + * The implementation must remove the spell from the database and update + * id, character_id member variables. + */ + virtual void unpublish(const character& ch, const spell& sp) = 0; + + /** + * Update the spell level in database. + * + * Only called when the level needs to be changed, the implementation does + * not need to update level_ field. + * + * \note called from set_level helper + * \throw std::exception if the operation could not succeed + */ + virtual void set_level(const character& ch, std::uint8_t level) = 0; +}; } // !server
--- a/libserver/malikania/server/net/auth_handler.cpp Tue Jan 09 13:15:07 2018 +0100 +++ b/libserver/malikania/server/net/auth_handler.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -33,7 +33,7 @@ { try { // TODO: VERIFY ALREADY LOGGED IN! - auto ac = server.database().account_dao().authenticate( + auto ac = server.database().accounts().authenticate( util::json::require_string(object, "/login"_json_pointer), util::json::require_string(object, "/password"_json_pointer) );
--- a/tests/libserver/dao-account/CMakeLists.txt Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -# -# CMakeLists.txt -- CMake build system for malikania -# -# Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -malikania_create_test( - NAME dao-account - LIBRARIES libmlk-server - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp - FLAGS - SQLITE_SHARED_LIBRARY="$<TARGET_FILE:db-sqlite>" -)
--- a/tests/libserver/dao-account/main.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * main.cpp -- test account_dao - * - * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define BOOST_TEST_MODULE "account_dao" -#include <boost/test/unit_test.hpp> - -#include <malikania/server/db/dynlib_database.hpp> -#include <malikania/server/db/account_dao.hpp> -#include <malikania/server/db/account.hpp> - -namespace mlk { - -namespace server { - -class fixture { -protected: - std::shared_ptr<dynlib_database> db_; - - fixture() - : db_(new dynlib_database()) - { - } -}; - -BOOST_FIXTURE_TEST_SUITE(account_dao_suite, fixture) - -BOOST_AUTO_TEST_CASE(save) -{ - auto ac = std::make_shared<account>("francis", nullptr); -} - -BOOST_AUTO_TEST_SUITE_END() - -} // !server - -} // !mlk
--- a/tests/libserver/dao-account/test.hpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -class @TEST_CLASS_NAME@ : public testing::Test { -protected: - mlk::database m_database; - mlk::account_dao m_dao; - - std::string kind() - { - static const std::string name = "@TEST_CLASS_NAME@"; - - return name; - } - - std::unordered_map<std::string, std::string> parameters() - { - assert(kind() == "TestAccountSqlite"); - - if (kind() == "TestAccountSqlite") { - return {{ "path", "@test-dao-account_BINARY_DIR@/test-account-dao.db" }}; - } - - return {}; - } - - std::string file() - { - assert(kind() == "TestAccountSqlite"); - - if (kind() == "TestAccountSqlite") { - return DRIVERDIR "sqlite.so"; - } - - return ""; - } - -public: - @TEST_CLASS_NAME@() - : m_database(file(), parameters()) - , m_dao(m_database) - { - m_dao.clear(); - - assert(m_dao.count() == 0U); - } -}; - -TEST_F(@TEST_CLASS_NAME@, create) -{ - try { - mlk::account ac; - - ac.name = "jean"; - ac.email = "jean@christophe.fr"; - ac.first_name = "Jean"; - ac.last_name = "Christophe"; - ac.password = "raw"; - - m_dao.create(ac); - - ASSERT_EQ(1U, m_dao.count()); - ASSERT_EQ(ac, m_dao.list()[0]); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } -} - -TEST_F(@TEST_CLASS_NAME@, update) -{ - try { - mlk::account ac; - - ac.name = "jean"; - ac.email = "jean@christophe.fr"; - ac.first_name = "Jean"; - ac.last_name = "Christophe"; - ac.password = "raw"; - - m_dao.create(ac); - - ac.email = "benoit@christophe.fr"; - ac.first_name = "Benoit"; - - m_dao.update(ac); - - mlk::account ac2 = m_dao.get(ac.id); - - ASSERT_EQ("jean", ac2.name); - ASSERT_EQ("benoit@christophe.fr", ac2.email); - ASSERT_EQ("Benoit", ac2.first_name); - } catch (const std::exception &ex) { - FAIL() << ex.what(); - } -}
--- a/tests/libserver/dao-character/CMakeLists.txt Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -# -# CMakeLists.txt -- CMake build system for malikania -# -# Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -malikania_create_test( - NAME dao-character - LIBRARIES libmlk-server - SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp - FLAGS - SQLITE_SHARED_LIBRARY="$<TARGET_FILE:db-sqlite>" -)
--- a/tests/libserver/dao-character/main.cpp Tue Jan 09 13:15:07 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * main.cpp -- test character_dao - * - * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define BOOST_TEST_MODULE "character_dao" -#include <boost/test/unit_test.hpp> - -#include <malikania/server/db/dynlib_database.hpp> -#include <malikania/server/db/account.hpp> -#include <malikania/server/db/account_dao.hpp> -#include <malikania/server/db/character_dao.hpp> -#include <malikania/server/db/character.hpp> - -namespace mlk { - -namespace server { - -class fixture { -protected: - std::shared_ptr<dynlib_database> db_; - - fixture() - : db_(new dynlib_database(SQLITE_SHARED_LIBRARY, { - { "path", CMAKE_CURRENT_BINARY_DIR "/character.db" } - })) - { - } -}; - -BOOST_FIXTURE_TEST_SUITE(character_dao_suite, fixture) - -BOOST_AUTO_TEST_CASE(save) -{ - { - auto ac = std::make_shared<account>(db_, "francis"); - ac->set_email("francis@world.org"); - ac->set_firstname("Francis"); - ac->set_lastname("Meyer"); - ac->save(); - - auto ch = std::make_shared<character>(db_, "blackmage"); - ac->add_character(ch); - - BOOST_TEST(ac->is_published()); - BOOST_TEST(ac == ch->account()); - BOOST_TEST(ac->characters().size() == 1U); - BOOST_TEST(ch->is_published()); - } - - auto ac = db_->account_dao()->find("francis"); - - BOOST_TEST(ac->email() == "francis@world.org"); - BOOST_TEST(ac->firstname() == "Francis"); - BOOST_TEST(ac->lastname() == "Meyer"); -} - -BOOST_AUTO_TEST_CASE(direct_save) -{ - auto ac = std::make_shared<account>(db_, "francis"); - ac->save(); - - auto ch = std::make_shared<character>(db_, "blackmage"); - ch->save(ac); - - BOOST_TEST(ac->is_published()); - BOOST_TEST(ch->is_published()); - BOOST_TEST(ac == ch->account()); -} - -BOOST_AUTO_TEST_CASE(remove) -{ - auto ac = std::make_shared<account>(db_, "francis"); - ac->save(); - auto ch = std::make_shared<character>(db_, "blackmage"); - ac->add_character(ch); - ac->remove_character(ch); - - BOOST_TEST(ch->is_draft()); - BOOST_TEST(ac->characters().size() == 0U); -} - -BOOST_AUTO_TEST_CASE(direct_remove) -{ - auto ac = std::make_shared<account>(db_, "francis"); - ac->save(); - auto ch = std::make_shared<character>(db_, "blackmage"); - ch->save(ac); - ch->remove(); - - BOOST_TEST(ch->is_draft()); - BOOST_TEST(ac->characters().size() == 0U); -} - -BOOST_AUTO_TEST_SUITE_END() - -} // !server - -} // !mlk
--- a/tests/libserver/db/account/main.cpp Tue Jan 09 13:15:07 2018 +0100 +++ b/tests/libserver/db/account/main.cpp Sat Mar 03 17:34:12 2018 +0100 @@ -19,103 +19,28 @@ #define BOOST_TEST_MODULE "database account" #include <boost/test/unit_test.hpp> -#include <malikania/server/db/test_database.hpp> -#include <malikania/server/db/broken_account.hpp> -#include <malikania/server/db/broken_character.hpp> +#include <malikania/server/db/broken_database.hpp> #include <malikania/server/db/database_fixture.hpp> namespace mlk { namespace server { -class account_fixture { -protected: - test_database db_; - - const nlohmann::json& accounts() const noexcept - { - return db_.data()["accounts"]; - } - - const nlohmann::json& get(std::int64_t id) const noexcept - { - return accounts().at(std::to_string(id)); - } -}; - -/* - * Basic suite using test database. - * ------------------------------------------------------------------ - */ -BOOST_FIXTURE_TEST_SUITE(draft_suite, account_fixture) - -/* - * account::set_password. - * ------------------------------------------------------------------ - */ -BOOST_AUTO_TEST_CASE(set_password) -{ - auto ac = db_.account_draft("markand", "nopassword"); - - ac->set_password("temporarypassword"); - - BOOST_TEST(accounts().empty()); -} - -/* - * account::set_email. - * ------------------------------------------------------------------ - */ -BOOST_AUTO_TEST_CASE(set_email) -{ - auto ac = db_.account_draft("markand", "nopassword"); - - ac->set_email("fake@malikania.fr"); - - BOOST_TEST(accounts().empty()); -} - -/* - * account::set_firstname. - * ------------------------------------------------------------------ - */ -BOOST_AUTO_TEST_CASE(set_firstname) -{ - auto ac = db_.account_draft("markand", "nopassword"); - - ac->set_firstname("Jean"); - - BOOST_TEST(accounts().empty()); -} - -/* - * account::set_lastname. - * ------------------------------------------------------------------ - */ -BOOST_AUTO_TEST_CASE(set_lastname) -{ - auto ac = db_.account_draft("markand", "nopassword"); - - ac->set_lastname("Bertrand"); - - BOOST_TEST(accounts().empty()); -} - -BOOST_AUTO_TEST_SUITE_END() - /* * Test behaviour with broken implementation. * ------------------------------------------------------------------ */ -BOOST_AUTO_TEST_SUITE(broken) -/* - * account::save. - * ------------------------------------------------------------------ - */ +class broken_fixture { +protected: + broken_database db_; +}; + +BOOST_FIXTURE_TEST_SUITE(broken_fixture_suite, broken_fixture) + BOOST_AUTO_TEST_CASE(save) { - broken_account ac("markand", "nopassword"); + account ac(db_, "markand", "nopassword"); try { ac.save(); @@ -124,13 +49,10 @@ BOOST_TEST(ac.is_draft()); } -/* - * account::remove. - * ------------------------------------------------------------------ - */ BOOST_AUTO_TEST_CASE(remove) { - broken_account ac("markand", "nopassword", broken_account::allow_flags::save); + db_.set_account_flags(broken_account_dao::allow_flags::publish); + account ac(db_, "markand", "nopassword"); ac.save(); @@ -141,13 +63,10 @@ BOOST_TEST(ac.is_published()); } -/* - * account::set_password. - * ------------------------------------------------------------------ - */ BOOST_AUTO_TEST_CASE(set_password) { - broken_account ac("markand", "nopassword", broken_account::allow_flags::save); + db_.set_account_flags(broken_account_dao::allow_flags::publish); + account ac(db_, "markand", "nopassword"); ac.save(); @@ -155,16 +74,13 @@ ac.set_password("newpassword"); } catch (...) {} - BOOST_TEST(ac.password() == "nopassword"); + BOOST_TEST(ac.get_password() == "nopassword"); } -/* - * account::set_email. - * ------------------------------------------------------------------ - */ BOOST_AUTO_TEST_CASE(set_email) { - broken_account ac("markand", "nopassword", broken_account::allow_flags::save); + db_.set_account_flags(broken_account_dao::allow_flags::publish); + account ac(db_, "markand", "nopassword"); ac.save(); @@ -172,16 +88,13 @@ ac.set_email("markand@malikania.fr"); } catch (...) {} - BOOST_TEST(ac.email() == ""); + BOOST_TEST(ac.get_email() == ""); } -/* - * account::set_firstname. - * ------------------------------------------------------------------ - */ BOOST_AUTO_TEST_CASE(set_firstname) { - broken_account ac("markand", "nopassword", broken_account::allow_flags::save); + db_.set_account_flags(broken_account_dao::allow_flags::publish); + account ac(db_, "markand", "nopassword"); ac.save(); @@ -189,16 +102,13 @@ ac.set_firstname("David"); } catch (...) {} - BOOST_TEST(ac.firstname() == ""); + BOOST_TEST(ac.get_firstname() == ""); } -/* - * account::set_lastname. - * ------------------------------------------------------------------ - */ BOOST_AUTO_TEST_CASE(set_lastname) { - broken_account ac("markand", "nopassword", broken_account::allow_flags::save); + db_.set_account_flags(broken_account_dao::allow_flags::publish); + account ac(db_, "markand", "nopassword"); ac.save(); @@ -206,24 +116,21 @@ ac.set_lastname("David"); } catch (...) {} - BOOST_TEST(ac.lastname() == ""); + BOOST_TEST(ac.get_lastname() == ""); } -/* - * account::add_character. - * ------------------------------------------------------------------ - */ BOOST_AUTO_TEST_CASE(add_character) { - broken_account ac("markand", "nopassword", broken_account::allow_flags::save); + db_.set_account_flags(broken_account_dao::allow_flags::publish); + account ac(db_, "markand", "nopassword"); ac.save(); try { - ac.add_character(std::make_unique<broken_character>("erekin", "fire")); + ac.add(character(db_, "erekin", "fire")); } catch (...) {} - BOOST_TEST(ac.characters().size() == 0U); + BOOST_TEST(ac.get_characters().size() == 0U); } BOOST_AUTO_TEST_SUITE_END() @@ -236,58 +143,60 @@ void fill(database& db) { - auto ac = db.account_draft("markand", "nopassword"); + account ac(db, "markand", "nopassword"); - ac->set_email("markand@malikania.fr"); - ac->set_firstname("David"); - ac->set_lastname("Demelier"); - ac->save(); + ac.set_email("markand@malikania.fr"); + ac.set_firstname("David"); + ac.set_lastname("Demelier"); + ac.save(); { - auto ch = db.character_draft("erekin", "blackmage"); - ch->set_level(75); - ac->add_character(std::move(ch)); + character ch(db, "erekin", "blackmage"); + + ch.set_level(100); + ac.add(std::move(ch)); } { - auto ch = db.character_draft("luna", "fairy"); - ch->set_level(45); - ac->add_character(std::move(ch)); + character ch(db, "luna", "fairy"); + + ch.set_level(45); + ac.add(std::move(ch)); } } + BOOST_AUTO_TEST_CASE_TEMPLATE(load, Database, database_types) { Database db; fill(db.db()); - auto ac = db.db().account_dao().find_by_login("markand"); + auto ac = db.db().accounts().find_by_login("markand"); - BOOST_TEST(ac->login() == "markand"); - BOOST_TEST(ac->password() == "nopassword"); - BOOST_TEST(ac->email() == "markand@malikania.fr"); - BOOST_TEST(ac->firstname() == "David"); - BOOST_TEST(ac->lastname() == "Demelier"); - BOOST_TEST(ac->characters().size() == 2U); + BOOST_TEST(ac->get_login() == "markand"); + BOOST_TEST(ac->get_password() == "nopassword"); + BOOST_TEST(ac->get_email() == "markand@malikania.fr"); + BOOST_TEST(ac->get_firstname() == "David"); + BOOST_TEST(ac->get_lastname() == "Demelier"); + BOOST_TEST(ac->get_characters().size() == 2U); - auto& erekin = ac->find_character([] (const auto& c) { - return c->nickname() == "erekin"; + const auto& characters = ac->get_characters(); + const auto erekin = std::find_if(characters.begin(), characters.end(), [] (const auto& c) { + return c.get_nickname() == "erekin"; }); - BOOST_TEST(erekin.get()); - BOOST_TEST(erekin->nickname() == "erekin"); - BOOST_TEST(erekin->classname() == "blackmage"); - BOOST_TEST(erekin->level() == 75U); + BOOST_TEST(erekin->get_nickname() == "erekin"); + BOOST_TEST(erekin->get_classname() == "blackmage"); + BOOST_TEST(erekin->get_level() == 100U); - auto& luna = ac->find_character([] (const auto& c) { - return c->nickname() == "luna"; + const auto luna = std::find_if(characters.begin(), characters.end(), [] (const auto& c) { + return c.get_nickname() == "luna"; }); - BOOST_TEST(luna.get()); - BOOST_TEST(luna->nickname() == "luna"); - BOOST_TEST(luna->classname() == "fairy"); - BOOST_TEST(luna->level() == 45U); + BOOST_TEST(luna->get_nickname() == "luna"); + BOOST_TEST(luna->get_classname() == "fairy"); + BOOST_TEST(luna->get_level() == 45U); } BOOST_AUTO_TEST_CASE_TEMPLATE(set_password, Database, database_types) @@ -295,9 +204,9 @@ Database db; fill(db.db()); - db.db().account_dao().find_by_login("markand")->set_password("hello"); + db.db().accounts().find_by_login("markand")->set_password("hello"); - BOOST_TEST(db.db().account_dao().find_by_login("markand")->password() == "hello"); + BOOST_TEST(db.db().accounts().find_by_login("markand")->get_password() == "hello"); } BOOST_AUTO_TEST_CASE_TEMPLATE(set_email, Database, database_types) @@ -305,9 +214,9 @@ Database db; fill(db.db()); - db.db().account_dao().find_by_login("markand")->set_email("no@spam.org"); + db.db().accounts().find_by_login("markand")->set_email("no@spam.org"); - BOOST_TEST(db.db().account_dao().find_by_login("markand")->email() == "no@spam.org"); + BOOST_TEST(db.db().accounts().find_by_login("markand")->get_email() == "no@spam.org"); } BOOST_AUTO_TEST_CASE_TEMPLATE(set_firstname, Database, database_types) @@ -315,9 +224,9 @@ Database db; fill(db.db()); - db.db().account_dao().find_by_login("markand")->set_firstname("Francis"); + db.db().accounts().find_by_login("markand")->set_firstname("Francis"); - BOOST_TEST(db.db().account_dao().find_by_login("markand")->firstname() == "Francis"); + BOOST_TEST(db.db().accounts().find_by_login("markand")->get_firstname() == "Francis"); } BOOST_AUTO_TEST_CASE_TEMPLATE(set_lastname, Database, database_types) @@ -325,36 +234,9 @@ Database db; fill(db.db()); - db.db().account_dao().find_by_login("markand")->set_lastname("Lalanne"); - - BOOST_TEST(db.db().account_dao().find_by_login("markand")->lastname() == "Lalanne"); -} - -BOOST_AUTO_TEST_CASE_TEMPLATE(remove_character, Database, database_types) -{ - Database db; - - fill(db.db()); - - { - auto ac = db.db().account_dao().find_by_login("markand"); + db.db().accounts().find_by_login("markand")->set_lastname("Lalanne"); - ac->remove_character( - ac->find_character([] (const auto& c) { - return c->nickname() == "luna"; - }) - ); - } - - auto ac = db.db().account_dao().find_by_login("markand"); - - BOOST_TEST(ac->characters().size() == 1U); - - auto& luna = ac->find_character([] (const auto& c) { - return c->nickname() == "luna"; - }); - - BOOST_TEST(!luna.get()); + BOOST_TEST(db.db().accounts().find_by_login("markand")->get_lastname() == "Lalanne"); } BOOST_AUTO_TEST_SUITE_END()