141 lines
6.0 KiB
C#
141 lines
6.0 KiB
C#
using System.Globalization;
|
|
using Domain;
|
|
using Npgsql;
|
|
using NpgsqlTypes;
|
|
|
|
namespace Infrastructure
|
|
{
|
|
public class PostgresRepository : IPostgresRepository
|
|
{
|
|
private readonly NpgsqlDataSource _dataSource;
|
|
|
|
public PostgresRepository(string connectionString)
|
|
{
|
|
_dataSource = NpgsqlDataSource.Create(connectionString);
|
|
}
|
|
|
|
public async Task<IDictionary<(string, double, int), Medicao>>
|
|
ObterMedicoesAsync(string codigoSCDE, DateTime dataIni, DateTime dataFim, CancellationToken ct)
|
|
{
|
|
var existentes = new Dictionary<(string, double, int), Medicao>();
|
|
|
|
string sql = @"
|
|
SELECT ponto, dia_num, minuto, origem, ativa_consumo, ativa_geracao, reativa_consumo, reativa_geracao
|
|
FROM med_5min
|
|
WHERE ponto = @ponto AND dia_num >= @data_ini AND dia_num <= @data_fim";
|
|
|
|
await using var command = _dataSource.CreateCommand(sql);
|
|
command.Parameters.AddWithValue("ponto", codigoSCDE + "P");
|
|
command.Parameters.AddWithValue("data_ini", dataIni.ToOADate());
|
|
command.Parameters.AddWithValue("data_fim", dataFim.ToOADate());
|
|
|
|
await using var reader = await command.ExecuteReaderAsync(ct);
|
|
while (await reader.ReadAsync(ct))
|
|
{
|
|
var medicao = new Medicao(
|
|
reader.GetString(0),
|
|
reader.GetDouble(1),
|
|
reader.GetInt32(2),
|
|
reader.GetString(3),
|
|
reader.IsDBNull(4) ? (double?)null : reader.GetDouble(4),
|
|
reader.IsDBNull(5) ? (double?)null : reader.GetDouble(5),
|
|
reader.IsDBNull(6) ? (double?)null : reader.GetDouble(6),
|
|
reader.IsDBNull(7) ? (double?)null : reader.GetDouble(7)
|
|
);
|
|
|
|
existentes[(medicao.Ponto, medicao.DiaNum, medicao.Minuto)] = medicao;
|
|
}
|
|
|
|
return existentes;
|
|
}
|
|
|
|
public async Task InserirMedicoesAsync(IEnumerable<Medicao> medicoes, CancellationToken ct)
|
|
{
|
|
await using var connection = await _dataSource.OpenConnectionAsync(ct);
|
|
using var writer = connection.BeginBinaryImport(
|
|
"COPY med_5min (origem, dia_num, minuto, ativa_consumo, ativa_geracao, reativa_consumo, reativa_geracao, ponto) FROM STDIN (FORMAT BINARY)");
|
|
|
|
foreach (var m in medicoes)
|
|
{
|
|
writer.StartRow();
|
|
writer.Write(m.Origem);
|
|
writer.Write(m.DiaNum, NpgsqlDbType.Numeric);
|
|
writer.Write(m.Minuto, NpgsqlDbType.Integer);
|
|
writer.Write(m.AtivaConsumo, NpgsqlDbType.Numeric);
|
|
writer.Write(m.AtivaGeracao, NpgsqlDbType.Numeric);
|
|
writer.Write(m.ReativaConsumo, NpgsqlDbType.Numeric);
|
|
writer.Write(m.ReativaGeracao, NpgsqlDbType.Numeric);
|
|
writer.Write(m.Ponto);
|
|
}
|
|
|
|
await writer.CompleteAsync();
|
|
}
|
|
public async Task AtualizarMedicoesAsync(IEnumerable<Medicao> medicoes, CancellationToken ct)
|
|
{
|
|
await using var connection = await _dataSource.OpenConnectionAsync(ct);
|
|
using var batch = new NpgsqlBatch(connection);
|
|
|
|
// Gerar os parâmetros dinamicamente, mantendo a abordagem parametrizada
|
|
var valores = medicoes
|
|
.Select((m, index) => new
|
|
{
|
|
Index = index,
|
|
Ponto = m.Ponto,
|
|
DiaNum = m.DiaNum,
|
|
Minuto = m.Minuto,
|
|
Origem = m.Origem,
|
|
AtivaConsumo = m.AtivaConsumo,
|
|
AtivaGeracao = m.AtivaGeracao,
|
|
ReativaConsumo = m.ReativaConsumo,
|
|
ReativaGeracao = m.ReativaGeracao
|
|
})
|
|
.ToList();
|
|
|
|
var query = @"
|
|
UPDATE med_5min
|
|
SET origem = nv.origem,
|
|
ativa_consumo = nv.ativa_consumo,
|
|
ativa_geracao = nv.ativa_geracao,
|
|
reativa_consumo = nv.reativa_consumo,
|
|
reativa_geracao = nv.reativa_geracao
|
|
FROM (VALUES";
|
|
|
|
// Adicionar os valores para o `VALUES`
|
|
for (int i = 0; i < valores.Count; i++)
|
|
{
|
|
query += $" (@ponto_{i}, @dia_num_{i}, @minuto_{i}, @origem_{i}, " +
|
|
$"@ativa_consumo_{i}, @ativa_geracao_{i}, @reativa_consumo_{i}, @reativa_geracao_{i})";
|
|
if (i < valores.Count - 1)
|
|
{
|
|
query += ", ";
|
|
}
|
|
}
|
|
|
|
query += @") AS nv (ponto, dia_num, minuto, origem, ativa_consumo, ativa_geracao, reativa_consumo, reativa_geracao)
|
|
WHERE med_5min.ponto = nv.ponto
|
|
AND med_5min.dia_num = nv.dia_num
|
|
AND med_5min.minuto = nv.minuto;";
|
|
|
|
// Agora, vamos adicionar os parâmetros à query
|
|
var cmd = new NpgsqlBatchCommand(query);
|
|
|
|
foreach (var valor in valores)
|
|
{
|
|
cmd.Parameters.AddWithValue($"ponto_{valor.Index}", valor.Ponto);
|
|
cmd.Parameters.AddWithValue($"dia_num_{valor.Index}", valor.DiaNum);
|
|
cmd.Parameters.AddWithValue($"minuto_{valor.Index}", valor.Minuto);
|
|
cmd.Parameters.AddWithValue($"origem_{valor.Index}", valor.Origem);
|
|
cmd.Parameters.AddWithValue($"ativa_consumo_{valor.Index}", valor.AtivaConsumo ?? (object)DBNull.Value);
|
|
cmd.Parameters.AddWithValue($"ativa_geracao_{valor.Index}", valor.AtivaGeracao ?? (object)DBNull.Value);
|
|
cmd.Parameters.AddWithValue($"reativa_consumo_{valor.Index}", valor.ReativaConsumo ?? (object)DBNull.Value);
|
|
cmd.Parameters.AddWithValue($"reativa_geracao_{valor.Index}", valor.ReativaGeracao ?? (object)DBNull.Value);
|
|
}
|
|
|
|
batch.BatchCommands.Add(cmd);
|
|
|
|
// Executar a query
|
|
await batch.ExecuteNonQueryAsync(ct);
|
|
}
|
|
}
|
|
}
|