Skip to content

Commit

Permalink
[DB] Add Transactions (#12)
Browse files Browse the repository at this point in the history
* cs# version bump

* add transaction method

* save cps with transaction;dot for millis

co-pilot = op
  • Loading branch information
tslashd authored Jan 29, 2024
1 parent ca7cdc0 commit 2f12703
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 13 deletions.
29 changes: 29 additions & 0 deletions src/ST-DB/DB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,33 @@ public async Task<int> Write(string query)
}
});
}

public async Task Transaction(List<string> commands)
{
if (this._db == null)
{
throw new InvalidOperationException("Database connection is not open.");
}

using (var transaction = await this._db.BeginTransactionAsync())
{
try
{
foreach (var command in commands)
{
using (var cmd = new MySqlCommand(command, this._db, transaction))
{
await cmd.ExecuteNonQueryAsync();
}
}

await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw; // rethrow the exception to be handled by the caller
}
}
}
}
4 changes: 2 additions & 2 deletions src/ST-Events/TriggerStartTouch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ internal HookResult OnTriggerStartTouch(DynamicHook handler)

// Add entry in DB for the run
if(!player.Timer.IsPracticeMode) {
AddTimer(1.5f, () => {
AddTimer(1.5f, async () => {
player.Stats.ThisRun.SaveMapTime(player, DB); // Save the MapTime PB data
player.Stats.LoadMapTimesData(player, DB); // Load the MapTime PB data again (will refresh the MapTime ID for the Checkpoints query)
player.Stats.ThisRun.SaveCurrentRunCheckpoints(player, DB); // Save this run's checkpoints
await player.Stats.ThisRun.SaveCurrentRunCheckpoints(player, DB); // Save this run's checkpoints
player.Stats.LoadCheckpointsData(DB); // Reload checkpoints for the run - we should really have this in `SaveMapTime` as well but we don't re-load PB data inside there so we need to do it here
CurrentMap.GetMapRecordAndTotals(DB); // Reload the Map record and totals for the HUD
});
Expand Down
2 changes: 1 addition & 1 deletion src/ST-Player/PlayerHUD.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static string FormatTime(int ticks, PlayerTimer.TimeFormatStyle style = P
{
case PlayerTimer.TimeFormatStyle.Compact:
return time.TotalMinutes < 1
? $"{time.Seconds:D1}:{millis:D3}"
? $"{time.Seconds:D1}.{millis:D3}"
: $"{time.Minutes:D1}:{time.Seconds:D1}.{millis:D3}";
case PlayerTimer.TimeFormatStyle.Full:
return $"{time.Hours:D2}:{time.Minutes:D2}:{time.Seconds:D2}.{millis:D3}";
Expand Down
15 changes: 6 additions & 9 deletions src/ST-Player/PlayerStats/CurrentRun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ INSERT INTO `MapTimes`
/// Saves the `CurrentRunCheckpoints` dictionary to the database
/// We need the correct `this.ID` to be populated before calling this method otherwise Query will fail
/// </summary>
public void SaveCurrentRunCheckpoints(Player player, TimerDatabase DB) // To-do: Transactions? Player sometimes rubberbands for a bit here
public async Task SaveCurrentRunCheckpoints(Player player, TimerDatabase DB)
{
int style = player.Timer.Style;
List<string> commands = new List<string>();
// Loop through the checkpoints and insert/update them in the database for the run
foreach (var item in player.Stats.ThisRun.Checkpoint)
{
Expand Down Expand Up @@ -105,26 +106,22 @@ INSERT INTO `Checkpoints`
#endif

// Insert/Update CPs to database
// To-do: Transactions?
// Check if the player has PB object initialized and if the player's character is currently active in the game
if (item.Value != null && player.Controller.PlayerPawn.Value != null)
{
Task<int> newPbTask = DB.Write($@"
string command = $@"
INSERT INTO `Checkpoints`
(`maptime_id`, `cp`, `run_time`, `start_vel_x`, `start_vel_y`, `start_vel_z`,
`end_vel_x`, `end_vel_y`, `end_vel_z`, `attempts`, `end_touch`)
VALUES ({player.Stats.PB[style].ID}, {cp}, {runTime}, {startVelX}, {startVelY}, {startVelZ}, {endVelX}, {endVelY}, {endVelZ}, {attempts}, {ticks})
ON DUPLICATE KEY UPDATE
run_time=VALUES(run_time), start_vel_x=VALUES(start_vel_x), start_vel_y=VALUES(start_vel_y), start_vel_z=VALUES(start_vel_z),
end_vel_x=VALUES(end_vel_x), end_vel_y=VALUES(end_vel_y), end_vel_z=VALUES(end_vel_z), attempts=VALUES(attempts), end_touch=VALUES(end_touch);
");
if (newPbTask.Result <= 0)
throw new Exception($"CS2 Surf ERROR >> internal class Checkpoint : PersonalBest -> SaveCurrentRunCheckpoints -> Inserting Checkpoints. CP: {cp} | Name: {player.Profile.Name}");

newPbTask.Dispose();
";
commands.Add(command);
}
}

await DB.Transaction(commands);
player.Stats.ThisRun.Checkpoint.Clear();
}
}
2 changes: 1 addition & 1 deletion src/SurfTimer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.147" />
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.159" />
<PackageReference Include="MaxMind.GeoIP2" Version="5.2.0" />
<PackageReference Include="MySqlConnector" Version="2.3.1" />
</ItemGroup>
Expand Down

0 comments on commit 2f12703

Please sign in to comment.