diff --git a/scripts/move_sqlite.py b/scripts/move_sqlite.py index 53bff3869..902192193 100755 --- a/scripts/move_sqlite.py +++ b/scripts/move_sqlite.py @@ -87,6 +87,7 @@ def main(): print() print((" echo '.dump --preserve-rowids' | sqlite3 {} | " + # including rowids, this forces sqlite to name all columns in each INSERT statement "grep -E '^INSERT INTO record_(race|teamrace|saves)' | " + # filter out inserts + "sed -e 's/INSERT INTO/INSERT IGNORE INTO/' | " + # ignore duplicate rows "sed -e 's/rowid,//' -e 's/VALUES([0-9]*,/VALUES(/' > {}") # filter out rowids again .format(os.path.abspath(args.to), sql_file)) print(" mysql -u teeworlds -p'PW2' teeworlds < {}".format(sql_file)) diff --git a/src/engine/server/databases/connection.cpp b/src/engine/server/databases/connection.cpp index c8b32c5d2..2004e81ee 100644 --- a/src/engine/server/databases/connection.cpp +++ b/src/engine/server/databases/connection.cpp @@ -22,6 +22,7 @@ void IDbConnection::FormatCreateRace(char *aBuf, unsigned int BufferSize) "cp25 FLOAT DEFAULT 0, " "GameID VARCHAR(64), " "DDNet7 BOOL DEFAULT FALSE" + "PRIMARY KEY (Map, Name, Time, Timestamp, Server)" ");", GetPrefix(), BinaryCollate(), MAX_NAME_LENGTH, BinaryCollate()); } @@ -37,6 +38,7 @@ void IDbConnection::FormatCreateTeamrace(char *aBuf, unsigned int BufferSize, co "ID %s NOT NULL, " // VARBINARY(16) for MySQL and BLOB for SQLite "GameID VARCHAR(64), " "DDNet7 BOOL DEFAULT FALSE" + "PRIMARY KEY (ID, Name)" ");", GetPrefix(), BinaryCollate(), MAX_NAME_LENGTH, BinaryCollate(), pIdType); } diff --git a/src/game/server/score.cpp b/src/game/server/score.cpp index 9d480b8b0..81c3903f5 100644 --- a/src/game/server/score.cpp +++ b/src/game/server/score.cpp @@ -508,7 +508,7 @@ bool CScore::SaveScoreThread(IDbConnection *pSqlServer, const ISqlData *pGameDat // save score. Can't fail, because no UNIQUE/PRIMARY KEY constrain is defined. str_format(aBuf, sizeof(aBuf), - "INSERT INTO %s_race(" + "INSERT IGNORE 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, " @@ -631,7 +631,7 @@ bool CScore::SaveTeamScoreThread(IDbConnection *pSqlServer, const ISqlData *pGam { // if no entry found... create a new one str_format(aBuf, sizeof(aBuf), - "INSERT INTO %s_teamrace(Map, Name, Timestamp, Time, ID, GameID, DDNet7) " + "INSERT IGNORE INTO %s_teamrace(Map, Name, Timestamp, Time, ID, GameID, DDNet7) " "VALUES (?, ?, %s, %.2f, ?, ?, false);", pSqlServer->GetPrefix(), pSqlServer->InsertTimestampAsUtc(), pData->m_Time); pSqlServer->PrepareStatement(aBuf); @@ -1321,7 +1321,7 @@ bool CScore::SaveTeamThread(IDbConnection *pSqlServer, const ISqlData *pGameData if(UseCode) { str_format(aBuf, sizeof(aBuf), - "INSERT INTO %s_saves(Savegame, Map, Code, Timestamp, Server, SaveID, DDNet7) " + "INSERT IGNORE INTO %s_saves(Savegame, Map, Code, Timestamp, Server, SaveID, DDNet7) " "VALUES (?, ?, ?, CURRENT_TIMESTAMP, ?, ?, false)", pSqlServer->GetPrefix()); pSqlServer->PrepareStatement(aBuf);