From eb4d77f0719f7770ad7f5c2000582ce5bea19d5b Mon Sep 17 00:00:00 2001 From: Zwelf Date: Sun, 12 Jul 2020 14:07:12 +0200 Subject: [PATCH] Make inserting ranks compatible with SQLite --- src/engine/server/databases/connection.h | 3 +++ src/engine/server/databases/mysql.cpp | 15 +++++++++++++++ src/engine/server/databases/mysql.h | 2 ++ src/engine/server/databases/sqlite.cpp | 15 +++++++++++++++ src/engine/server/databases/sqlite.h | 2 ++ src/game/server/score.cpp | 21 ++++++--------------- 6 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/engine/server/databases/connection.h b/src/engine/server/databases/connection.h index 9b14e7bc9..17ad211d1 100644 --- a/src/engine/server/databases/connection.h +++ b/src/engine/server/databases/connection.h @@ -55,6 +55,9 @@ public: // returns number of bytes read into the buffer virtual int GetBlob(int Col, unsigned char *pBuffer, int BufferSize) const = 0; + // SQL statements, that can't be abstracted, has side effects to the result + virtual void AddPoints(const char *pPlayer, int Points) = 0; + private: char m_aPrefix[64]; diff --git a/src/engine/server/databases/mysql.cpp b/src/engine/server/databases/mysql.cpp index 803e9a879..b19f7e169 100644 --- a/src/engine/server/databases/mysql.cpp +++ b/src/engine/server/databases/mysql.cpp @@ -273,3 +273,18 @@ int CMysqlConnection::GetBlob(int Col, unsigned char *pBuffer, int BufferSize) c return 0; #endif } + +void CMysqlConnection::AddPoints(const char *pPlayer, int Points) +{ + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), + "INSERT INTO %s_points(Name, Points) " + "VALUES (?, ?) " + "ON DUPLICATE KEY UPDATE Points=Points+?;", + GetPrefix()); + PrepareStatement(aBuf); + BindString(1, pPlayer); + BindInt(2, Points); + BindInt(3, Points); + Step(); +} diff --git a/src/engine/server/databases/mysql.h b/src/engine/server/databases/mysql.h index a9fd55fb3..50d6c475b 100644 --- a/src/engine/server/databases/mysql.h +++ b/src/engine/server/databases/mysql.h @@ -49,6 +49,8 @@ public: virtual void GetString(int Col, char *pBuffer, int BufferSize) const; virtual int GetBlob(int Col, unsigned char *pBuffer, int BufferSize) const; + virtual void AddPoints(const char *pPlayer, int Points); + private: #if defined(CONF_SQL) std::unique_ptr m_pConnection; diff --git a/src/engine/server/databases/sqlite.cpp b/src/engine/server/databases/sqlite.cpp index c15227980..6e12da6b4 100644 --- a/src/engine/server/databases/sqlite.cpp +++ b/src/engine/server/databases/sqlite.cpp @@ -193,3 +193,18 @@ void CSqliteConnection::ExceptionOnError(int Result) throw std::runtime_error(sqlite3_errmsg(m_pDb)); } } + +void CSqliteConnection::AddPoints(const char *pPlayer, int Points) +{ + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), + "INSERT INTO %s_points(Name, Points) " + "VALUES (?, ?) " + "ON CONFLICT(Name) UPDATE SET Points=Points+?;", + GetPrefix()); + PrepareStatement(aBuf); + BindString(1, pPlayer); + BindInt(2, Points); + BindInt(3, Points); + Step(); +} diff --git a/src/engine/server/databases/sqlite.h b/src/engine/server/databases/sqlite.h index f68c05185..d31eb2442 100644 --- a/src/engine/server/databases/sqlite.h +++ b/src/engine/server/databases/sqlite.h @@ -37,6 +37,8 @@ public: // passing a negative buffer size is undefined behavior virtual int GetBlob(int Col, unsigned char *pBuffer, int BufferSize) const; + virtual void AddPoints(const char *pPlayer, int Points); + private: // copy of config vars char m_aFilename[512]; diff --git a/src/game/server/score.cpp b/src/game/server/score.cpp index 615c22fdb..e7ab990bb 100644 --- a/src/game/server/score.cpp +++ b/src/game/server/score.cpp @@ -453,26 +453,16 @@ bool CScore::SaveScoreThread(IDbConnection *pSqlServer, const ISqlData *pGameDat if(pSqlServer->Step()) { int Points = pSqlServer->GetInt(1); + pSqlServer->AddPoints(pData->m_Name, Points); str_format(paMessages[0], sizeof(paMessages[0]), "You earned %d point%s for finishing this map!", Points, Points == 1 ? "" : "s"); - - str_format(aBuf, sizeof(aBuf), - "INSERT INTO %s_points(Name, Points) " - "VALUES (?, ?) " - "ON duplicate key " - "UPDATE Name=VALUES(Name), Points=Points+VALUES(Points);", - pSqlServer->GetPrefix()); - pSqlServer->PrepareStatement(aBuf); - pSqlServer->BindString(1, pData->m_Name); - pSqlServer->BindInt(1, Points); - pSqlServer->Step(); } } - // save score + // save score. Can't fail, because no UNIQUE/PRIMARY KEY constrain is defined. str_format(aBuf, sizeof(aBuf), - "INSERT IGNORE INTO %s_race(" + "INSERT INTO %s_race(" "Map, Name, Timestamp, Time, Server, " "cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8, cp9, cp10, cp11, cp12, cp13, " "cp14, cp15, cp16, cp17, cp18, cp19, cp20, cp21, cp22, cp23, cp24, cp25, " @@ -481,7 +471,7 @@ bool CScore::SaveScoreThread(IDbConnection *pSqlServer, const ISqlData *pGameDat "%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, " "%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, " "%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, " - "'%s', false);", + "?, false);", pSqlServer->GetPrefix(), pData->m_Time, pData->m_aCpCurrent[0], pData->m_aCpCurrent[1], pData->m_aCpCurrent[2], pData->m_aCpCurrent[3], pData->m_aCpCurrent[4], pData->m_aCpCurrent[5], @@ -491,12 +481,13 @@ bool CScore::SaveScoreThread(IDbConnection *pSqlServer, const ISqlData *pGameDat pData->m_aCpCurrent[15], pData->m_aCpCurrent[16], pData->m_aCpCurrent[17], pData->m_aCpCurrent[18], pData->m_aCpCurrent[19], pData->m_aCpCurrent[20], pData->m_aCpCurrent[21], pData->m_aCpCurrent[22], pData->m_aCpCurrent[23], - pData->m_aCpCurrent[24], pData->m_GameUuid); + pData->m_aCpCurrent[24]); pSqlServer->PrepareStatement(aBuf); pSqlServer->BindString(1, pData->m_Map); pSqlServer->BindString(2, pData->m_Name); pSqlServer->BindString(3, pData->m_aTimestamp); pSqlServer->BindString(4, g_Config.m_SvSqlServerName); + pSqlServer->BindString(5, pData->m_GameUuid); pSqlServer->Step(); pData->m_pResult->m_Done = true;