Compare commits
4 commits
develop
...
feature/st
Author | SHA1 | Date | |
---|---|---|---|
Serraniel | 3d975eddc7 | ||
Serraniel | 3e40948f79 | ||
Serraniel | 2a239dba58 | ||
Serraniel | 91eb7fea58 |
111
Docs/SweetLib.Storage
Normal file
111
Docs/SweetLib.Storage
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>SweetLib.Storage</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:SweetLib.Storage.Database.IDatabaseObject`1">
|
||||
<summary>
|
||||
Object to store in database.
|
||||
</summary>
|
||||
<typeparam name="T">Type of the used identifier.</typeparam>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.Database.IDatabaseObject`1.AssignFieldNames">
|
||||
<summary>
|
||||
Assigns field names of the database columns.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.Database.IDatabaseObject`1.AssignToAsync(System.Data.Common.DbParameterCollection)">
|
||||
<summary>
|
||||
Assigns values to the query parameters.
|
||||
</summary>
|
||||
<param name="parameters"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.Database.IDatabaseObject`1.AssignFromAsync(System.Data.Common.DbDataReader)">
|
||||
<summary>
|
||||
Assigns values to the object.
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.Database.IDatabaseObject`1.TableName">
|
||||
<summary>
|
||||
Table name of the object.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:SweetLib.Storage.IConnectionProvider`1">
|
||||
<summary>
|
||||
Provider for database connection.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.IConnectionProvider`1.GetConnection">
|
||||
<summary>
|
||||
Gets an instance of a database connection.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:SweetLib.Storage.IIdentified`1">
|
||||
<summary>
|
||||
Interface for identified objects.
|
||||
</summary>
|
||||
<typeparam name="T">Type of the identifier.</typeparam>
|
||||
</member>
|
||||
<member name="P:SweetLib.Storage.IIdentified`1.Id">
|
||||
<summary>
|
||||
Identifier of the object.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.IIdentified`1.UnidentifiedId">
|
||||
<summary>
|
||||
Gets a dummy Id for unidentified instances;
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:SweetLib.Storage.IIdGenerator`1">
|
||||
<summary>
|
||||
Generates a new object id.
|
||||
</summary>
|
||||
<typeparam name="T">Type of the used identifier.</typeparam>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.IIdGenerator`1.GenerateNewId">
|
||||
<summary>
|
||||
Generates a new id of the specified type.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.IIdGenerator`1.GenerateNewIdAsync">
|
||||
<summary>
|
||||
Generates a new id of the specified type. Runs asynchronous.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:SweetLib.Storage.IStorable`1">
|
||||
<summary>
|
||||
Interface for objects which can be stored and restored.
|
||||
</summary>
|
||||
<typeparam name="T">Type of the used identifier.</typeparam>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.IStorable`1.Store">
|
||||
<summary>
|
||||
Stores the object.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.IStorable`1.Restore(`0)">
|
||||
<summary>
|
||||
Restores an object.
|
||||
</summary>
|
||||
<param name="identifier">Identifier of the object to restore.</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:SweetLib.Storage.IStorable`1.IsNew">
|
||||
<summary>
|
||||
Determines whether the current object instance is new or already exists.
|
||||
</summary>
|
||||
<returns>Boolean indicating if the current object instance is new or already exists.</returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
8
Docs/SweetLib.Storage.MySql
Normal file
8
Docs/SweetLib.Storage.MySql
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>SweetLib.Storage.MySql</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
7
Docs/SweetLib.Storage.md
Normal file
7
Docs/SweetLib.Storage.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
<a name='contents'></a>
|
||||
# Contents [#](#contents 'Go To Here')
|
||||
|
||||
|
||||
|
||||
<a name='assembly'></a>
|
||||
# SweetLib.Storage.MySql [#](#assembly 'Go To Here') [=](#contents 'Back To Contents')
|
121
SweetLib.Storage.MySql/CustomMySqlObject.cs
Normal file
121
SweetLib.Storage.MySql/CustomMySqlObject.cs
Normal file
|
@ -0,0 +1,121 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using SweetLib.Storage.Database;
|
||||
using SweetLib.Storage.MySql.Helper;
|
||||
|
||||
namespace SweetLib.Storage.MySql;
|
||||
|
||||
public abstract class CustomMySqlObject<T> : IDatabaseObject<T>
|
||||
{
|
||||
protected CustomMySqlObject(IDatabaseConnectionProvider connectionProvider,
|
||||
IIdGenerator<T> idGenerator)
|
||||
{
|
||||
ConnectionProvider = connectionProvider;
|
||||
IdGenerator = idGenerator;
|
||||
Id = UnidentifiedId();
|
||||
}
|
||||
|
||||
protected IDatabaseConnectionProvider ConnectionProvider { get; }
|
||||
protected IIdGenerator<T> IdGenerator { get; }
|
||||
|
||||
public T Id { get; set; }
|
||||
public abstract T UnidentifiedId();
|
||||
|
||||
public async Task Store()
|
||||
{
|
||||
var wasNew = IsNew();
|
||||
|
||||
var connection = ConnectionProvider!.GetConnection();
|
||||
await connection.OpenAsync();
|
||||
try
|
||||
{
|
||||
var command = connection.CreateCommand();
|
||||
try
|
||||
{
|
||||
command.CommandText = wasNew ? InsertCommand() : UpdateCommand();
|
||||
await AssignToAsync(command.Parameters);
|
||||
await command.ExecuteNonQueryAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Avoid invalid ID if new object could not be stored
|
||||
if (wasNew)
|
||||
Id = UnidentifiedId();
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNew()
|
||||
{
|
||||
return Id.Equals(UnidentifiedId());
|
||||
}
|
||||
|
||||
public virtual IEnumerable<string> AssignFieldNames()
|
||||
{
|
||||
var result = new List<string>();
|
||||
result.Add(IdFieldName());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual async Task AssignToAsync(DbParameterCollection parameters)
|
||||
{
|
||||
if (IsNew()) Id = await IdGenerator.GenerateNewIdAsync();
|
||||
|
||||
parameters.AddMySqlParameterWithValue("@Id", Id);
|
||||
}
|
||||
|
||||
public virtual async Task AssignFromAsync(DbDataReader reader)
|
||||
{
|
||||
await reader.ReadAsync();
|
||||
Id = (T)reader["Id"];
|
||||
}
|
||||
|
||||
public abstract string TableName();
|
||||
|
||||
public async Task<bool> Restore(T identifier)
|
||||
{
|
||||
var connection = ConnectionProvider!.GetConnection();
|
||||
await connection.OpenAsync();
|
||||
try
|
||||
{
|
||||
var command = connection.CreateCommand();
|
||||
command.CommandText = $"SELECT * FROM {TableName()} WHERE Id=@id";
|
||||
command.Parameters.AddMySqlParameterWithValue("@id", identifier);
|
||||
|
||||
var reader = await command.ExecuteReaderAsync();
|
||||
if (!reader.HasRows)
|
||||
return false;
|
||||
|
||||
await AssignFromAsync(reader);
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
connection.Close();
|
||||
}
|
||||
}
|
||||
|
||||
internal string InsertCommand()
|
||||
{
|
||||
var fields = AssignFieldNames();
|
||||
return
|
||||
$"INSERT INTO {TableName()} ({string.Join(",", fields)}) VALUES ({string.Join(",", fields.Select(f => $"@{f}"))})";
|
||||
}
|
||||
|
||||
internal string UpdateCommand()
|
||||
{
|
||||
var fields = AssignFieldNames();
|
||||
return $"UPDATE {TableName()} SET {string.Join(",", fields.Select(f => $"{f}=@{f}"))}";
|
||||
}
|
||||
|
||||
public abstract string IdFieldName();
|
||||
}
|
16
SweetLib.Storage.MySql/Helper/DbParameterExtensions.cs
Normal file
16
SweetLib.Storage.MySql/Helper/DbParameterExtensions.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System.Data.Common;
|
||||
using MySqlConnector;
|
||||
|
||||
namespace SweetLib.Storage.MySql.Helper;
|
||||
|
||||
public static class MySqlDbParameterExtensions
|
||||
{
|
||||
public static MySqlParameter AddMySqlParameterWithValue(this DbParameterCollection parameterCollection,
|
||||
string name, object value)
|
||||
{
|
||||
var param = new MySqlParameter(name, value);
|
||||
parameterCollection.Add(param);
|
||||
|
||||
return param;
|
||||
}
|
||||
}
|
50
SweetLib.Storage.MySql/SweetLib.Storage.MySql.csproj
Normal file
50
SweetLib.Storage.MySql/SweetLib.Storage.MySql.csproj
Normal file
|
@ -0,0 +1,50 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Version>0.1.0-alpha.1</Version>
|
||||
<Description>SweetLib MySql Storage package</Description>
|
||||
<Authors>Serraniel</Authors>
|
||||
<Company />
|
||||
<Copyright>Copyright © 2017-2022 by Serraniel</Copyright>
|
||||
<PackageLicenseUrl></PackageLicenseUrl>
|
||||
<PackageProjectUrl>https://github.com/Serraniel/SweetLib</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/Serraniel/SweetLib</RepositoryUrl>
|
||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||
<PackageIconUrl>https://github.com/Serraniel/SweetLib/blob/develop/nuget_icon.png?raw=true</PackageIconUrl>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||
<AssemblyVersion>0.1.0.3</AssemblyVersion>
|
||||
<FileVersion>0.1.0.3</FileVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DocumentationFile>bin\Release\netstandard1.3\SweetLib.IO.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>..\Docs\SweetLib.Storage.MySql</DocumentationFile>
|
||||
<OutputPath></OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MySqlConnector" Version="2.2.5" />
|
||||
<PackageReference Include="Vsxmd" Version="1.4.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\LICENSE">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath></PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SweetLib.Storage\SweetLib.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
18
SweetLib.Storage.MySql/SweetLib.Storage.MySql.nuspec
Normal file
18
SweetLib.Storage.MySql/SweetLib.Storage.MySql.nuspec
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0"?>
|
||||
<package >
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$-alpha</version>
|
||||
<title>$title$</title>
|
||||
<authors>Serraniel</authors>
|
||||
<owners>$author$</owners>
|
||||
<licenseUrl>https://opensource.org/licenses/GPL-3.0</licenseUrl>
|
||||
<projectUrl>https://github.com/Serraniel/SweetLib</projectUrl>
|
||||
<iconUrl>https://github.com/Serraniel/SweetLib/blob/develop/nuget_icon.png?raw=true</iconUrl>
|
||||
<requireLicenseAcceptance>true</requireLicenseAcceptance>
|
||||
<description>$description$</description>
|
||||
<releaseNotes>First pre version just to try that nuget package thing :)</releaseNotes>
|
||||
<copyright>Copyright © 2017 Serraniel</copyright>
|
||||
<tags>Utility</tags>
|
||||
</metadata>
|
||||
</package>
|
2
SweetLib.Storage.MySql/build-nuget.bat
Normal file
2
SweetLib.Storage.MySql/build-nuget.bat
Normal file
|
@ -0,0 +1,2 @@
|
|||
nuget pack SweetLib.Storage.MySql.csproj -properties Configuration=Release -symbols
|
||||
pause
|
8
SweetLib.Storage/Database/IDatabaseConnectionProvider.cs
Normal file
8
SweetLib.Storage/Database/IDatabaseConnectionProvider.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using System.Data.Common;
|
||||
|
||||
namespace SweetLib.Storage.Database
|
||||
{
|
||||
public interface IDatabaseConnectionProvider : IConnectionProvider<DbConnection>
|
||||
{
|
||||
}
|
||||
}
|
39
SweetLib.Storage/Database/IDatabaseObject.cs
Normal file
39
SweetLib.Storage/Database/IDatabaseObject.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SweetLib.Storage.Database
|
||||
{
|
||||
/// <summary>
|
||||
/// Object to store in database.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the used identifier.</typeparam>
|
||||
public interface IDatabaseObject<T> : IStorable<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Assigns field names of the database columns.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerable<string> AssignFieldNames();
|
||||
|
||||
/// <summary>
|
||||
/// Assigns values to the query parameters.
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns></returns>
|
||||
Task AssignToAsync(DbParameterCollection parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Assigns values to the object.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <returns></returns>
|
||||
Task AssignFromAsync(DbDataReader reader);
|
||||
|
||||
/// <summary>
|
||||
/// Table name of the object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string TableName();
|
||||
}
|
||||
}
|
16
SweetLib.Storage/IConnectionProvider.cs
Normal file
16
SweetLib.Storage/IConnectionProvider.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System.Data;
|
||||
|
||||
namespace SweetLib.Storage
|
||||
{
|
||||
/// <summary>
|
||||
/// Provider for database connection.
|
||||
/// </summary>
|
||||
public interface IConnectionProvider<out T> where T : IDbConnection
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an instance of a database connection.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
T GetConnection();
|
||||
}
|
||||
}
|
23
SweetLib.Storage/IIdGenerator.cs
Normal file
23
SweetLib.Storage/IIdGenerator.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace SweetLib.Storage
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a new object id.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the used identifier.</typeparam>
|
||||
public interface IIdGenerator<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a new id of the specified type.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
T GenerateNewId();
|
||||
|
||||
/// <summary>
|
||||
/// Generates a new id of the specified type. Runs asynchronous.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<T> GenerateNewIdAsync();
|
||||
}
|
||||
}
|
20
SweetLib.Storage/IIdentified.cs
Normal file
20
SweetLib.Storage/IIdentified.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
namespace SweetLib.Storage
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for identified objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the identifier.</typeparam>
|
||||
public interface IIdentified<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifier of the object.
|
||||
/// </summary>
|
||||
T Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dummy Id for unidentified instances;
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
T UnidentifiedId();
|
||||
}
|
||||
}
|
30
SweetLib.Storage/IStorable.cs
Normal file
30
SweetLib.Storage/IStorable.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace SweetLib.Storage
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for objects which can be stored and restored.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the used identifier.</typeparam>
|
||||
public interface IStorable<T> : IIdentified<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores the object.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task Store();
|
||||
|
||||
/// <summary>
|
||||
/// Restores an object.
|
||||
/// </summary>
|
||||
/// <param name="identifier">Identifier of the object to restore.</param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Restore(T identifier);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current object instance is new or already exists.
|
||||
/// </summary>
|
||||
/// <returns>Boolean indicating if the current object instance is new or already exists.</returns>
|
||||
bool IsNew();
|
||||
}
|
||||
}
|
|
@ -28,8 +28,10 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SweetLib" Version="0.2.1-alpha" />
|
||||
<PackageReference Include="Vsxmd" Version="1.2.0" />
|
||||
<PackageReference Include="Vsxmd" Version="1.4.5">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SweetLib.IO", "SweetLib.IO\
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SweetLib.Storage", "SweetLib.Storage\SweetLib.Storage.csproj", "{E08BDA4B-BA1E-44F8-9D97-D11F80F8F9F0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SweetLib.Storage.MySql", "SweetLib.Storage.MySql\SweetLib.Storage.MySql.csproj", "{EEDC1D23-1CA9-4A1D-85CB-C71E73E10B12}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -43,6 +45,10 @@ Global
|
|||
{E08BDA4B-BA1E-44F8-9D97-D11F80F8F9F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E08BDA4B-BA1E-44F8-9D97-D11F80F8F9F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E08BDA4B-BA1E-44F8-9D97-D11F80F8F9F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EEDC1D23-1CA9-4A1D-85CB-C71E73E10B12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EEDC1D23-1CA9-4A1D-85CB-C71E73E10B12}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EEDC1D23-1CA9-4A1D-85CB-C71E73E10B12}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EEDC1D23-1CA9-4A1D-85CB-C71E73E10B12}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in a new issue