DD.WellWorkover.Cloud/ConsoleApp1/Program.cs
2022-10-06 13:49:20 +05:00

105 lines
3.7 KiB
C#

using AsbCloudApp.Data;
using AsbCloudApp.Data.DailyReport;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Services.DailyReport;
using ClosedXML.Excel;
using DocumentFormat.OpenXml.Wordprocessing;
using Microsoft.EntityFrameworkCore;
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
private static AsbCloudDbContext db = ServiceFactory.Context;
public static async Task<(int oldCount, int newCount)> RediceSamplingAsync(int idTelemetry, int ratio, int maxDateGapSec, CancellationToken token)
{
const int ramLimit = 30 * 1024 * 1024;
const int dataItemSize = 345; // by profiler
const int itemsCountLimit = ramLimit / dataItemSize; // ~ 90_000
const int maxWellDepthGap = 1;
ratio = ratio > 0 ? ratio : 5;
maxDateGapSec = maxDateGapSec > 0 ? maxDateGapSec : 9;
var dbset = db.Set<TelemetryDataSaub>();
var sqlSelect =
"select " +
" * " +
"from " +
" (select " +
" *, " +
" rank() over win1 as row_num, " +
" lag(\"date\", 1) over win1 as lag_date, " +
" lag(\"mode\", 1) over win1 as lag_mode, " +
" lag(mse_state, 1) over win1 as lag_mse_state, " +
" lag(well_depth, 1) over win1 as lag_well_depth, " +
" lag(id_feed_regulator, 1) over win1 as lag_id_feed_regulator " +
" from t_telemetry_data_saub " +
$" where id_telemetry = {idTelemetry} and \"date\" > {{0}}" +
" window win1 as (order by \"date\") " +
" ) as ttt " +
"where " +
$" (row_num % {ratio}) = 0 " +
" or \"mode\" != lag_mode " +
$" or(\"date\" - lag_date) > interval '{maxDateGapSec} second' " +
$" or well_depth - lag_well_depth > {maxWellDepthGap} " +
" or mse_state != lag_mse_state " +
" or id_feed_regulator != lag_id_feed_regulator " +
"order by \"date\" ";
var sqlDelete = "delete " +
"from t_telemetry_data_saub " +
$"where id_telemetry = {idTelemetry} and \"date\" between {{0}} and {{1}};";
var startDate = DateTimeOffset.MinValue;
var iteration = 0;
var deleted = 0;
var saved = 0;
do
{
var query = dbset
.FromSqlRaw(sqlSelect, startDate)
.AsNoTracking();
var data = await query
.Take(itemsCountLimit)
.ToArrayAsync(token);
var currentDataCount = data.Length;
if (currentDataCount == 0)
break;
var lastDate = data.Last().DateTime;
var currentDeleted = await db.Database.ExecuteSqlRawAsync(sqlDelete, new object[]{ startDate, lastDate}.AsEnumerable(), token);
if (currentDeleted == 0)
break;
dbset.AddRange(data);
await db.SaveChangesAsync(token);
startDate = lastDate;
deleted += currentDeleted;
saved += currentDataCount;
iteration++;
} while (true);
return (deleted, saved);
}
// use ServiceFactory to make services
static void Main(/*string[] args*/)
{
RediceSamplingAsync(183, 5, 10, CancellationToken.None).Wait();
}
}
}