61 lines
2.4 KiB
C#
61 lines
2.4 KiB
C#
|
|
||
|
|
||
|
using System.Collections.Immutable;
|
||
|
using HermesSocketLibrary.db;
|
||
|
|
||
|
namespace HermesSocketServer.Store.Internal
|
||
|
{
|
||
|
public abstract class AutoSavedStore<K, V> : GroupSaveStore<K, V> where K : class where V : class
|
||
|
{
|
||
|
private readonly GroupSaveSqlGenerator<V> _generator;
|
||
|
private readonly DatabaseTable _table;
|
||
|
private readonly Database _database;
|
||
|
private readonly Serilog.ILogger _logger;
|
||
|
|
||
|
|
||
|
public AutoSavedStore(DatabaseTable table, Database database, Serilog.ILogger logger)
|
||
|
: base(logger)
|
||
|
{
|
||
|
_generator = new GroupSaveSqlGenerator<V>(table.PropertyMapping, logger);
|
||
|
_table = table;
|
||
|
_database = database;
|
||
|
_logger = logger;
|
||
|
}
|
||
|
|
||
|
public override async Task Save()
|
||
|
{
|
||
|
var allColumns = _table.KeyColumns.Union(_table.DataColumns).ToArray();
|
||
|
|
||
|
await GenerateQuery(_added,
|
||
|
(size) => _generator.GeneratePreparedInsertSql(_table.TableName, size, allColumns),
|
||
|
async (query, _, values) => await _generator.DoPreparedStatement(_database, query, values, allColumns));
|
||
|
|
||
|
await GenerateQuery(_modified,
|
||
|
(size) => _generator.GeneratePreparedUpdateSql(_table.TableName, size, _table.KeyColumns, _table.DataColumns),
|
||
|
async (query, _, values) => await _generator.DoPreparedStatement(_database, query, values, allColumns));
|
||
|
|
||
|
await GenerateQuery(_deleted,
|
||
|
(size) => _generator.GeneratePreparedDeleteSql(_table.TableName, size, _table.KeyColumns),
|
||
|
async (query, keys, _) => await _generator.DoPreparedStatementRaw(_database, query, keys, _table.KeyColumns));
|
||
|
}
|
||
|
|
||
|
private async Task GenerateQuery(IList<K> keys, Func<int, string> generate, Func<string, IEnumerable<K>, IEnumerable<V>, Task> execute)
|
||
|
{
|
||
|
ImmutableList<K>? list = null;
|
||
|
lock (_lock)
|
||
|
{
|
||
|
if (!keys.Any())
|
||
|
return;
|
||
|
|
||
|
list = keys.ToImmutableList();
|
||
|
keys.Clear();
|
||
|
}
|
||
|
|
||
|
var query = generate(list.Count);
|
||
|
_logger.Debug($"{_table.TableName} - Adding {list.Count} rows to database: {query}");
|
||
|
|
||
|
var values = list.Select(id => _store[id]).Where(v => v != null);
|
||
|
await execute(query, list, values);
|
||
|
}
|
||
|
}
|
||
|
}
|