Skip to content

Commit

Permalink
Add SQLite
Browse files Browse the repository at this point in the history
  • Loading branch information
MSWS committed Aug 31, 2024
1 parent 745ba4f commit a8056a0
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 18 deletions.
6 changes: 6 additions & 0 deletions Gangs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GangsImpl.Mock", "GangsImpl
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GangsImpl.SQL", "GangsImpl.SQL\GangsImpl.SQL.csproj", "{7F519D8B-63B5-4628-9806-5E9FE79F9797}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GangsImpl.SQLite", "GangsImpl.SQLite\GangsImpl.SQLite.csproj", "{F87CD126-3D2D-47B7-A11E-93987772D1B0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -36,5 +38,9 @@ Global
{7F519D8B-63B5-4628-9806-5E9FE79F9797}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F519D8B-63B5-4628-9806-5E9FE79F9797}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F519D8B-63B5-4628-9806-5E9FE79F9797}.Release|Any CPU.Build.0 = Release|Any CPU
{F87CD126-3D2D-47B7-A11E-93987772D1B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F87CD126-3D2D-47B7-A11E-93987772D1B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F87CD126-3D2D-47B7-A11E-93987772D1B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F87CD126-3D2D-47B7-A11E-93987772D1B0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
36 changes: 24 additions & 12 deletions GangsImpl.SQL/SQLStatManager.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Data;
using Dapper;
using Dapper;
using GangsAPI.Data.Stat;
using GangsAPI.Services;
using MySqlConnector;
Expand All @@ -10,25 +9,35 @@ public class SQLStatManager(string connectionString,
string table = "gang_stats") : IStatManager {
private readonly HashSet<IStat> stats = [];
private MySqlConnection connection = null!;
private MySqlTransaction transaction = null!;

public void Start() {
connection = new MySqlConnection(connectionString);

connection.Open();
var command = connection.CreateCommand();
command.CommandText =
$"CREATE TABLE IF NOT EXISTS {table} (StatId VARCHAR(255) PRIMARY KEY, Name VARCHAR(255), Description TEXT)";
command.ExecuteNonQuery();
transaction = connection.BeginTransaction();

try {
var command = connection.CreateCommand();

connection.Query<SQLStat>($"SELECT * FROM {table}")
.ToList()
.ForEach(stat => stats.Add(stat));
command.Transaction = transaction;
command.CommandText =
$"CREATE TEMPORARY TABLE IF NOT EXISTS {table} (StatId VARCHAR(255) PRIMARY KEY, Name VARCHAR(255), Description TEXT)";
command.ExecuteNonQuery();

connection
.Query<SQLStat>($"SELECT * FROM {table}", transaction: transaction)
.ToList()
.ForEach(stat => stats.Add(stat));
} catch (Exception e) {
transaction.Rollback();
throw new InvalidOperationException("Failed initializing the database",
e);
}
}

public void Dispose() {
var command = connection.CreateCommand();
command.CommandText = $"DROP TABLE IF EXISTS {table}";
command.ExecuteNonQuery();
transaction.Rollback();
connection.Close();
connection.Dispose();
}
Expand All @@ -50,8 +59,10 @@ public async Task<IEnumerable<IStat>> GetStats() {
}

public async Task<bool> RegisterStat(IStat stat) {
if (stats.Contains(stat)) return false;
var sqlStat = (SQLStat)stat;
var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText =
$"INSERT INTO {table} (StatId, Name, Description) VALUES (@StatId, @Name, @Description)";
command.Parameters.AddWithValue("@StatId", sqlStat.StatId);
Expand All @@ -66,6 +77,7 @@ public async Task<bool> UnregisterStat(string id) {
foreach (var stat in matches) stats.Remove(stat);

var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = $"DELETE FROM {table} WHERE StatId = @StatId";
command.Parameters.AddWithValue("@StatId", id);
await command.ExecuteNonQueryAsync();
Expand Down
20 changes: 20 additions & 0 deletions GangsImpl.SQLite/GangsImpl.SQLite.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>GangsImpl.SQLLite</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.8" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GangsAPI\GangsAPI.csproj" />
<ProjectReference Include="..\GangsImpl.SQL\GangsImpl.SQL.csproj" />
</ItemGroup>

</Project>
88 changes: 88 additions & 0 deletions GangsImpl.SQLite/SQLiteStatManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Dapper;
using GangsAPI.Data.Stat;
using GangsAPI.Services;
using GangsImpl.SQL;
using Microsoft.Data.Sqlite;

namespace GangsImpl.SQLLite;

public class SQLiteStatManager(string connectionString,
string table = "gang_stats") : IStatManager {
private readonly HashSet<IStat> stats = [];
private SqliteConnection connection = null!;
private SqliteTransaction transaction = null!;

public void Start() {
connection = new SqliteConnection(connectionString);

connection.Open();
transaction = connection.BeginTransaction();

try {
var command = connection.CreateCommand();

command.Transaction = transaction;
command.CommandText =
$"CREATE TEMPORARY TABLE IF NOT EXISTS {table} (StatId VARCHAR(255) PRIMARY KEY, Name VARCHAR(255), Description TEXT)";
command.ExecuteNonQuery();

connection
.Query<SQLStat>($"SELECT * FROM {table}", transaction: transaction)
.ToList()
.ForEach(stat => stats.Add(stat));
} catch (Exception e) {
transaction.Rollback();
throw new InvalidOperationException("Failed initializing the database",
e);
}
}

public void Dispose() {
transaction.Rollback();
connection.Close();
connection.Dispose();
}

public async Task<IEnumerable<IStat>> GetStats() {
return await Task.FromResult<IEnumerable<IStat>>(stats);
}

public Task<IStat?> GetStat(string id) {
return Task.FromResult(stats.FirstOrDefault(stat => stat.StatId == id));
}

public async Task<IStat?> CreateStat(string id, string name,
string? description = null) {
var stat = await GetStat(id);
if (stat != null) return stat;
stat = new SQLStat { StatId = id, Name = name, Description = description };
return stat;
}

public async Task<bool> RegisterStat(IStat stat) {
if (stats.Contains(stat)) return false;
var sqlStat = (SQLStat)stat;
var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText =
$"INSERT INTO {table} (StatId, Name, Description) VALUES (@StatId, @Name, @Description)";
command.Parameters.AddWithValue("@StatId", sqlStat.StatId);
command.Parameters.AddWithValue("@Name", sqlStat.Name);
command.Parameters.AddWithValue("@Description", sqlStat.Description);
await command.ExecuteNonQueryAsync();
return stats.Add(stat);
}

public async Task<bool> UnregisterStat(string id) {
var matches = stats.Where(stat => stat.StatId == id).ToList();
foreach (var stat in matches) stats.Remove(stat);

var command = connection.CreateCommand();
command.Transaction = transaction;
command.CommandText = $"DELETE FROM {table} WHERE StatId = @StatId";
command.Parameters.AddWithValue("@StatId", id);
await command.ExecuteNonQueryAsync();

return await Task.FromResult(matches.Count > 0);
}
}
1 change: 1 addition & 0 deletions GangsTest/GangsTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

<ItemGroup>
<ProjectReference Include="..\GangsImpl.Mock\GangsImpl.Mock.csproj"/>
<ProjectReference Include="..\GangsImpl.SQLite\GangsImpl.SQLite.csproj" />
<ProjectReference Include="..\GangsImpl.SQL\GangsImpl.SQL.csproj"/>
</ItemGroup>

Expand Down
10 changes: 5 additions & 5 deletions GangsTest/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ namespace GangsTest;

public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddScoped<IPlayerManager, MockPlayerManager>();
services.AddScoped<IGangManager, MockGangManager>();
services.AddScoped<IStatManager, MockStatManager>();
services.AddScoped<IGangStatManager, MockInstanceStatManager>();
services.AddScoped<IPlayerStatManager, MockInstanceStatManager>();
services.AddSingleton<IPlayerManager, MockPlayerManager>();
services.AddSingleton<IGangManager, MockGangManager>();
services.AddSingleton<IStatManager, MockStatManager>();
services.AddSingleton<IGangStatManager, MockInstanceStatManager>();
services.AddSingleton<IPlayerStatManager, MockInstanceStatManager>();
}
}
5 changes: 4 additions & 1 deletion GangsTest/StatTests/StatManagerData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
using GangsAPI;
using GangsImpl.Memory;
using GangsImpl.SQL;
using GangsImpl.SQLLite;

namespace GangsTest.StatTests;

public class StatManagerData : IEnumerable<object[]> {
private readonly IBehavior[] behaviors = [
new MockStatManager(),
new SQLStatManager("Server=localhost;User=root;Database=gang", "gang_unit_test")
new SQLStatManager("Server=localhost;User=root;Database=gang",
"gang_unit_test"),
new SQLiteStatManager("Data Source=:memory:", "gang_unit_test")
];

public StatManagerData() {
Expand Down

0 comments on commit a8056a0

Please sign in to comment.