Check for potential duplicates before inserting.

This commit is contained in:
Pentarctagon 2021-11-10 10:34:46 -06:00 committed by Pentarctagon
parent 565ba530df
commit b08be54e65
No known key found for this signature in database
GPG key ID: 9456BC54A21DBFA0
6 changed files with 40 additions and 9 deletions

View file

@ -325,16 +325,17 @@ void dbconn::insert_game_player_info(const std::string& uuid, int game_id, const
log_sql_exception("Failed to insert game player info row for UUID `"+uuid+"` and game ID `"+std::to_string(game_id)+"`", e);
}
}
void dbconn::insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version)
unsigned long long dbconn::insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version)
{
try
{
modify(connection_, "INSERT INTO `"+db_game_content_info_table_+"`(INSTANCE_UUID, GAME_ID, TYPE, NAME, ID, SOURCE, VERSION) VALUES(?, ?, ?, ?, ?, ?, ?)",
return modify(connection_, "INSERT INTO `"+db_game_content_info_table_+"`(INSTANCE_UUID, GAME_ID, TYPE, NAME, ID, SOURCE, VERSION) VALUES(?, ?, ?, ?, ?, ?, ?)",
uuid, game_id, type, name, id, source, version);
}
catch(const mariadb::exception::base& e)
{
log_sql_exception("Failed to insert game content info row for UUID `"+uuid+"` and game ID `"+std::to_string(game_id)+"`", e);
return 0;
}
}
void dbconn::set_oos_flag(const std::string& uuid, int game_id)
@ -380,7 +381,7 @@ unsigned long long dbconn::insert_login(const std::string& username, const std::
{
try
{
return modify(connection_, "INSERT INTO `"+db_connection_history_table_+"`(USER_NAME, IP, VERSION) values(lower(?), ?, ?)",
return modify_get_id(connection_, "INSERT INTO `"+db_connection_history_table_+"`(USER_NAME, IP, VERSION) values(lower(?), ?, ?)",
username, ip, version);
}
catch(const mariadb::exception::base& e)
@ -531,6 +532,21 @@ mariadb::result_set_ref dbconn::select(mariadb::connection_ref connection, const
}
template<typename... Args>
unsigned long long dbconn::modify(mariadb::connection_ref connection, const std::string& sql, Args&&... args)
{
try
{
mariadb::statement_ref stmt = query(connection, sql, args...);
unsigned long long count = stmt->execute();
return count;
}
catch(const mariadb::exception::base& e)
{
ERR_SQL << "SQL query failed for query: `"+sql+"`" << std::endl;
throw e;
}
}
template<typename... Args>
unsigned long long dbconn::modify_get_id(mariadb::connection_ref connection, const std::string& sql, Args&&... args)
{
try
{

View file

@ -137,7 +137,7 @@ class dbconn
/**
* @see forum_user_handler::db_insert_game_content_info().
*/
void insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version);
unsigned long long insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version);
/**
* @see forum_user_handler::db_set_oos_flag().
@ -283,6 +283,17 @@ class dbconn
template<typename... Args>
unsigned long long modify(mariadb::connection_ref connection, const std::string& sql, Args&&... args);
/**
* Executes non-select statements (ie: insert, update, delete), but primarily intended for inserts that return a generated ID.
*
* @param connection The database connecion that will be used to execute the query.
* @param sql The SQL text to be executed.
* @param args The parameterized values to be inserted into the query.
* @return The value of an AUTO_INCREMENT column on the table being modified.
*/
template<typename... Args>
unsigned long long modify_get_id(mariadb::connection_ref connection, const std::string& sql, Args&&... args);
/**
* Begins recursively unpacking of the parameter pack in order to be able to call the correct parameterized setters on the query.
*

View file

@ -219,8 +219,8 @@ void fuh::db_insert_game_player_info(const std::string& uuid, int game_id, const
conn_.insert_game_player_info(uuid, game_id, username, side_number, is_host, faction, version, source, current_user);
}
void fuh::db_insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version){
conn_.insert_game_content_info(uuid, game_id, type, name, id, source, version);
unsigned long long fuh::db_insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version){
return conn_.insert_game_content_info(uuid, game_id, type, name, id, source, version);
}
void fuh::db_set_oos_flag(const std::string& uuid, int game_id){

View file

@ -180,8 +180,9 @@ public:
* @param id The id of the content.
* @param source The source add-on for the content.
* @param version The version of the source add-on.
* @return The number of rows inserted which should always be 1.
*/
void db_insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version);
unsigned long long db_insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version);
/**
* Sets the OOS flag in the database if wesnothd is told by a client it has detected an OOS error.

View file

@ -140,7 +140,7 @@ public:
virtual void db_insert_game_info(const std::string& uuid, int game_id, const std::string& version, const std::string& name, int reload, int observers, int is_public, int has_password) = 0;
virtual void db_update_game_end(const std::string& uuid, int game_id, const std::string& replay_location) = 0;
virtual void db_insert_game_player_info(const std::string& uuid, int game_id, const std::string& username, int side_number, int is_host, const std::string& faction, const std::string& version, const std::string& source, const std::string& current_user) = 0;
virtual void db_insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version) = 0;
virtual unsigned long long db_insert_game_content_info(const std::string& uuid, int game_id, const std::string& type, const std::string& name, const std::string& id, const std::string& source, const std::string& version) = 0;
virtual void db_set_oos_flag(const std::string& uuid, int game_id) = 0;
virtual void async_test_query(boost::asio::io_service& io_service, int limit) = 0;
virtual bool db_topic_id_exists(int topic_id) = 0;

View file

@ -1689,7 +1689,10 @@ void server::handle_player_in_game(player_iterator p, simple_wml::document& data
// [addon] info handling
for(const auto& addon : m.children("addon")) {
for(const auto& content : addon->children("content")) {
user_handler_->db_insert_game_content_info(uuid_, g.db_id(), content->attr("type").to_string(), content->attr("name").to_string(), content->attr("id").to_string(), addon->attr("id").to_string(), addon->attr("version").to_string());
unsigned long long rows_inserted = user_handler_->db_insert_game_content_info(uuid_, g.db_id(), content->attr("type").to_string(), content->attr("name").to_string(), content->attr("id").to_string(), addon->attr("id").to_string(), addon->attr("version").to_string());
if(rows_inserted == 0) {
WRN_SERVER << "Did not insert content row for [addon] data with uuid '" << uuid_ <<"', game ID '" << g.db_id() << "', type '" << content->attr("type").to_string() << "', and content ID '" << content->attr("id").to_string() << "'\n";
}
}
}