From e16b154578118f137c9b619bbbbf4f96999d132d Mon Sep 17 00:00:00 2001 From: "ns.potapov" Date: Fri, 17 May 2024 01:11:47 +0400 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8E=20=D1=81?= =?UTF-8?q?=D0=BB=D1=83=D1=87=D0=B0=D0=B9=D0=BD=D1=8B=D1=85=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/AbstractLogic.cs | 31 ++++- Medical/MedicalDatabaseContracts/ILogic.cs | 12 +- Medical/MedicalDatabaseContracts/IStorage.cs | 12 +- .../AbstractPostgresqlStorage.cs | 64 +++++++-- Medical/MedicalView/FormAbstractList.cs | 2 +- Medical/MedicalView/FormMain.Designer.cs | 36 ++++- Medical/MedicalView/FormMain.cs | 28 +++- Medical/MedicalView/Visits/FormVisit.cs | 131 +++++++++++++++++- 8 files changed, 282 insertions(+), 34 deletions(-) diff --git a/Medical/MedicalBusinessLogic/BusinessLogics/AbstractLogic.cs b/Medical/MedicalBusinessLogic/BusinessLogics/AbstractLogic.cs index af00003..59b30cc 100644 --- a/Medical/MedicalBusinessLogic/BusinessLogics/AbstractLogic.cs +++ b/Medical/MedicalBusinessLogic/BusinessLogics/AbstractLogic.cs @@ -26,6 +26,27 @@ namespace MedicalBusinessLogic.BusinessLogics protected abstract V GetViewModel(M model); + public bool DeleteAll(out double elapsedMilliseconds) + { + elapsedMilliseconds = 0; + try + { + _storage.DeleteAll(out elapsedMilliseconds); + _logger.LogInformation($"Delete ALL operation success"); + return true; + } + catch (Exception ex) + { + _logger.LogWarning($"Delete ALL operation failed: {ex.Message}"); + return false; + } + } + + public bool DeleteAll() + { + return DeleteAll(out _); + } + public bool Create(M model) { return Create(model, out _); @@ -51,7 +72,7 @@ namespace MedicalBusinessLogic.BusinessLogics return Update(model, out _); } - public virtual List ReadList(out long elapsedMilliseconds, S? searchModel = null) + public virtual List ReadList(out double elapsedMilliseconds, S? searchModel = null) { var elements = _storage.GetAll(out elapsedMilliseconds); @@ -64,7 +85,7 @@ namespace MedicalBusinessLogic.BusinessLogics return elements.Select(x => GetViewModel(x)).ToList(); } - public virtual V? ReadElement(int id, out long elapsedMilliseconds) + public virtual V? ReadElement(int id, out double elapsedMilliseconds) { var element = _storage.Get(id, out elapsedMilliseconds); if (element == null) @@ -76,7 +97,7 @@ namespace MedicalBusinessLogic.BusinessLogics return GetViewModel(element); } - public virtual bool Create(M model, out long elapsedMilliseconds) + public virtual bool Create(M model, out double elapsedMilliseconds) { elapsedMilliseconds = 0; try @@ -93,7 +114,7 @@ namespace MedicalBusinessLogic.BusinessLogics } } - public virtual bool Update(M model, out long elapsedMilliseconds) + public virtual bool Update(M model, out double elapsedMilliseconds) { elapsedMilliseconds = 0; try @@ -110,7 +131,7 @@ namespace MedicalBusinessLogic.BusinessLogics } } - public virtual bool Delete(int id, out long elapsedMilliseconds) + public virtual bool Delete(int id, out double elapsedMilliseconds) { elapsedMilliseconds = 0; try diff --git a/Medical/MedicalDatabaseContracts/ILogic.cs b/Medical/MedicalDatabaseContracts/ILogic.cs index 8a53c1a..d2ee1df 100644 --- a/Medical/MedicalDatabaseContracts/ILogic.cs +++ b/Medical/MedicalDatabaseContracts/ILogic.cs @@ -10,14 +10,16 @@ namespace MedicalDatabaseContracts where S : AbstractSearchModel { List ReadList(S? searchModel = null); - List ReadList(out long elapsedMilliseconds, S? searchModel = null); + List ReadList(out double elapsedMilliseconds, S? searchModel = null); V? ReadElement(int id); - V? ReadElement(int id, out long elapsedMilliseconds); + V? ReadElement(int id, out double elapsedMilliseconds); bool Create(M model); - bool Create(M model, out long elapsedMilliseconds); + bool Create(M model, out double elapsedMilliseconds); bool Update(M model); - bool Update(M model, out long elapsedMilliseconds); + bool Update(M model, out double elapsedMilliseconds); bool Delete(int id); - bool Delete(int id, out long elapsedMilliseconds); + bool Delete(int id, out double elapsedMilliseconds); + bool DeleteAll(); + bool DeleteAll(out double elapsedMilliseconds); } } diff --git a/Medical/MedicalDatabaseContracts/IStorage.cs b/Medical/MedicalDatabaseContracts/IStorage.cs index 2702f7f..6f47fc9 100644 --- a/Medical/MedicalDatabaseContracts/IStorage.cs +++ b/Medical/MedicalDatabaseContracts/IStorage.cs @@ -4,15 +4,17 @@ namespace MedicalDatabaseContracts { public interface IStorage where T : AbstractModel { - T? Get(int id, out long elapsedMilliseconds); + T? Get(int id, out double elapsedMilliseconds); T? Get(int id); - List GetAll(out long elapsedMilliseconds); + List GetAll(out double elapsedMilliseconds); List GetAll(); - void Insert(T item, out long elapsedMilliseconds); + void Insert(T item, out double elapsedMilliseconds); void Insert(T item); - void Update(T item, out long elapsedMilliseconds); + void Update(T item, out double elapsedMilliseconds); void Update(T item); - void Delete(int id, out long elapsedMilliseconds); + void Delete(int id, out double elapsedMilliseconds); void Delete(int id); + void DeleteAll(out double elapsedMilliseconds); + void DeleteAll(); } } diff --git a/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs b/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs index 3535edc..ed12432 100644 --- a/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs +++ b/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs @@ -3,6 +3,7 @@ using MedicalDatabaseContracts.Models; using Microsoft.Extensions.Logging; using Npgsql; using System.Diagnostics; +using System.Text; namespace MedicalPostgresqlDatabase { @@ -13,6 +14,9 @@ namespace MedicalPostgresqlDatabase protected readonly string PRIMARY_KEY_COLUMN_NAME; protected readonly string PRIMARY_KEY_SEQUENCE_NAME; + protected readonly string TIME_LOG_FILENAME_SUFFIX; + protected readonly string TIME_LOG_FOLDERNAME; + protected AbstractPostgresqlStorage( ILogger> logger, string tableName, @@ -23,17 +27,52 @@ namespace MedicalPostgresqlDatabase TABLE_NAME = tableName; PRIMARY_KEY_COLUMN_NAME = primaryKeyColumnName; PRIMARY_KEY_SEQUENCE_NAME = primary_key_sequence_name; + + TIME_LOG_FILENAME_SUFFIX = "sqltimelog.csv"; + TIME_LOG_FOLDERNAME = "timelogs"; } protected abstract T CreateEntityFromReader(NpgsqlDataReader reader); protected abstract Dictionary GetEntityAttributesDictionary(T item); + public void DeleteAll(out double elapsedMilliseconds) + { + using var connection = GetConnection(); + connection.Open(); + using var cmd = new NpgsqlCommand($"DELETE FROM {TABLE_NAME}", connection); + _logger.LogDebug(cmd.CommandText); + Stopwatch stopwatch = new(); + stopwatch.Start(); + cmd.ExecuteNonQuery(); + stopwatch.Stop(); + elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; + WriteTimeToFile(stopwatch, "DELETEALL"); + } + public void DeleteAll() + { + DeleteAll(out _); + } + + protected void WriteTimeToFile(Stopwatch stopwatch, string filenamePrefix) + { + if (!Directory.Exists(TIME_LOG_FOLDERNAME)) + { + Directory.CreateDirectory(TIME_LOG_FOLDERNAME); + } + string filename = GetType().Name + "_" + filenamePrefix + "_" + TIME_LOG_FILENAME_SUFFIX; + string path = Path.Combine(TIME_LOG_FOLDERNAME, filename); + using (StreamWriter sw = new StreamWriter(path, true)) + { + sw.WriteLine(stopwatch.Elapsed.TotalMilliseconds); + } + } + public virtual void Delete(int id) { Delete(id, out _); } - public virtual void Delete(int id, out long elapsedMilliseconds) + public virtual void Delete(int id, out double elapsedMilliseconds) { using var connection = GetConnection(); connection.Open(); @@ -44,13 +83,14 @@ namespace MedicalPostgresqlDatabase stopwatch.Start(); cmd.ExecuteNonQuery(); stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; + WriteTimeToFile(stopwatch, "DELETE"); } public virtual T? Get(int id) { return Get(id, out _); } - public virtual T? Get(int id, out long elapsedMilliseconds) + public virtual T? Get(int id, out double elapsedMilliseconds) { using var connection = GetConnection(); connection.Open(); @@ -61,7 +101,8 @@ namespace MedicalPostgresqlDatabase stopwatch.Start(); using var reader = cmd.ExecuteReader(); stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; + WriteTimeToFile(stopwatch, "GET"); if (reader.Read()) { return CreateEntityFromReader(reader); @@ -72,7 +113,7 @@ namespace MedicalPostgresqlDatabase { return GetAll(out _); } - public virtual List GetAll(out long elapsedMilliseconds) + public virtual List GetAll(out double elapsedMilliseconds) { var items = new List(); using var connection = GetConnection(); @@ -83,7 +124,8 @@ namespace MedicalPostgresqlDatabase stopwatch.Start(); using var reader = cmd.ExecuteReader(); stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; + WriteTimeToFile(stopwatch, "GETALL"); while (reader.Read()) { items.Add(CreateEntityFromReader(reader)); @@ -94,7 +136,7 @@ namespace MedicalPostgresqlDatabase { Insert(item, out _); } - public virtual void Insert(T item, out long elapsedMilliseconds) + public virtual void Insert(T item, out double elapsedMilliseconds) { using var connection = GetConnection(); connection.Open(); @@ -133,13 +175,14 @@ namespace MedicalPostgresqlDatabase stopwatch.Start(); cmd.ExecuteNonQuery(); stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; + WriteTimeToFile(stopwatch, "INSERT"); } public virtual void Update(T item) { Update(item, out _); } - public virtual void Update(T item, out long elapsedMilliseconds) + public virtual void Update(T item, out double elapsedMilliseconds) { using var connection = GetConnection(); connection.Open(); @@ -176,7 +219,8 @@ namespace MedicalPostgresqlDatabase stopwatch.Start(); cmd.ExecuteNonQuery(); stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + elapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; + WriteTimeToFile(stopwatch, "UPDATE"); } protected NpgsqlConnection GetConnection() diff --git a/Medical/MedicalView/FormAbstractList.cs b/Medical/MedicalView/FormAbstractList.cs index ce1bc82..f32f8f1 100644 --- a/Medical/MedicalView/FormAbstractList.cs +++ b/Medical/MedicalView/FormAbstractList.cs @@ -93,7 +93,7 @@ namespace MedicalView SetStatusStripText("Загрузка списка..."); try { - long elapsed; + double elapsed; var items = _logic.ReadList(out elapsed); dataGridView.DataSource = items; diff --git a/Medical/MedicalView/FormMain.Designer.cs b/Medical/MedicalView/FormMain.Designer.cs index ff94621..222745d 100644 --- a/Medical/MedicalView/FormMain.Designer.cs +++ b/Medical/MedicalView/FormMain.Designer.cs @@ -36,6 +36,7 @@ пациентыToolStripMenuItem1 = new ToolStripMenuItem(); dataGridView = new DataGridView(); panel = new Panel(); + buttonGenerateRandomData = new Button(); buttonEdit = new Button(); buttonDelete = new Button(); buttonAdd = new Button(); @@ -43,6 +44,7 @@ comboBoxDoctor = new ComboBox(); statusStrip = new StatusStrip(); toolStripStatusLabel = new ToolStripStatusLabel(); + buttonDeleteAllData = new Button(); menuStrip.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit(); panel.SuspendLayout(); @@ -56,7 +58,7 @@ menuStrip.Location = new Point(0, 0); menuStrip.Name = "menuStrip"; menuStrip.Padding = new Padding(7, 3, 0, 3); - menuStrip.Size = new Size(863, 30); + menuStrip.Size = new Size(1012, 30); menuStrip.TabIndex = 0; menuStrip.Text = "menuStrip1"; // @@ -109,11 +111,13 @@ dataGridView.RowHeadersWidth = 51; dataGridView.RowTemplate.Height = 25; dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect; - dataGridView.Size = new Size(863, 331); + dataGridView.Size = new Size(1012, 331); dataGridView.TabIndex = 1; // // panel // + panel.Controls.Add(buttonDeleteAllData); + panel.Controls.Add(buttonGenerateRandomData); panel.Controls.Add(buttonEdit); panel.Controls.Add(buttonDelete); panel.Controls.Add(buttonAdd); @@ -123,9 +127,19 @@ panel.Location = new Point(0, 30); panel.Margin = new Padding(3, 4, 3, 4); panel.Name = "panel"; - panel.Size = new Size(863, 39); + panel.Size = new Size(1012, 39); panel.TabIndex = 2; // + // buttonGenerateRandomData + // + buttonGenerateRandomData.Location = new Point(716, 5); + buttonGenerateRandomData.Name = "buttonGenerateRandomData"; + buttonGenerateRandomData.Size = new Size(135, 29); + buttonGenerateRandomData.TabIndex = 5; + buttonGenerateRandomData.Text = "Сгенерировать"; + buttonGenerateRandomData.UseVisualStyleBackColor = true; + buttonGenerateRandomData.Click += buttonGenerateRandomData_Click; + // // buttonEdit // buttonEdit.Anchor = AnchorStyles.Left; @@ -188,7 +202,7 @@ statusStrip.Items.AddRange(new ToolStripItem[] { toolStripStatusLabel }); statusStrip.Location = new Point(0, 379); statusStrip.Name = "statusStrip"; - statusStrip.Size = new Size(863, 22); + statusStrip.Size = new Size(1012, 22); statusStrip.TabIndex = 3; statusStrip.Text = "statusStrip1"; // @@ -197,11 +211,21 @@ toolStripStatusLabel.Name = "toolStripStatusLabel"; toolStripStatusLabel.Size = new Size(0, 16); // + // buttonDeleteAllData + // + buttonDeleteAllData.Location = new Point(857, 5); + buttonDeleteAllData.Name = "buttonDeleteAllData"; + buttonDeleteAllData.Size = new Size(143, 29); + buttonDeleteAllData.TabIndex = 6; + buttonDeleteAllData.Text = "Очистить базу"; + buttonDeleteAllData.UseVisualStyleBackColor = true; + buttonDeleteAllData.Click += buttonDeleteAllData_Click; + // // FormMain // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(863, 401); + ClientSize = new Size(1012, 401); Controls.Add(statusStrip); Controls.Add(panel); Controls.Add(dataGridView); @@ -239,5 +263,7 @@ private Button buttonEdit; private StatusStrip statusStrip; private ToolStripStatusLabel toolStripStatusLabel; + private Button buttonGenerateRandomData; + private Button buttonDeleteAllData; } } \ No newline at end of file diff --git a/Medical/MedicalView/FormMain.cs b/Medical/MedicalView/FormMain.cs index 096b191..16ee077 100644 --- a/Medical/MedicalView/FormMain.cs +++ b/Medical/MedicalView/FormMain.cs @@ -69,7 +69,7 @@ namespace MedicalView.Visits SetStatusStripText("Загрузка списка..."); try { - long elapsed; + double elapsed; var items = _visitLogic.ReadList(out elapsed); dataGridView.DataSource = items; @@ -150,5 +150,31 @@ namespace MedicalView.Visits } } } + + private void buttonGenerateRandomData_Click(object sender, EventArgs e) + { + if (MessageBox.Show("Сшенерировать случайные данные?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + var service = Program.ServiceProvider?.GetService(typeof(FormVisit)); + if (service is FormVisit form) + { + form.GenerateRandomDatabaseData(); + LoadData(); + } + } + } + + private void buttonDeleteAllData_Click(object sender, EventArgs e) + { + if (MessageBox.Show("Удалить ВСЕ данные?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + var service = Program.ServiceProvider?.GetService(typeof(FormVisit)); + if (service is FormVisit form) + { + form.DeleteAllDatabaseData(); + LoadData(); + } + } + } } } diff --git a/Medical/MedicalView/Visits/FormVisit.cs b/Medical/MedicalView/Visits/FormVisit.cs index b9aab61..385a665 100644 --- a/Medical/MedicalView/Visits/FormVisit.cs +++ b/Medical/MedicalView/Visits/FormVisit.cs @@ -14,12 +14,14 @@ namespace MedicalView.Visits private readonly ILogic _diagnoseLogic; private readonly ILogic _doctorLogic; private readonly ILogic _patientLogic; + private readonly ILogic _specLogic; public FormVisit( ILogger logger, ILogic visitLogic, ILogic diagnoseLogic, ILogic doctorLogic, - ILogic patientLogic) + ILogic patientLogic, + ILogic specLogic) { InitializeComponent(); _logger = logger; @@ -27,6 +29,7 @@ namespace MedicalView.Visits _diagnoseLogic = diagnoseLogic; _doctorLogic = doctorLogic; _patientLogic = patientLogic; + _specLogic = specLogic; } private void ApplyToolStripMenuItem_Click(object sender, EventArgs e) @@ -100,7 +103,7 @@ namespace MedicalView.Visits { textBoxComment.Text = view.Comment; datePicker.Value = view.Date.ToDateTime(view.Time); - timePicker.Value = view.Date.ToDateTime(view.Time); + timePicker.Value = view.Date.ToDateTime(view.Time); if (view.DiagnoseId != null) { comboBoxDiagnose.SelectedIndex = diagnoses.FindIndex(x => x.Id == view.DiagnoseId); @@ -116,5 +119,129 @@ namespace MedicalView.Visits } } } + + public void DeleteAllDatabaseData() + { + try + { + _logger.LogInformation("Удаление всех данных БД"); + _visitLogic.DeleteAll(); + _diagnoseLogic.DeleteAll(); + _doctorLogic.DeleteAll(); + _specLogic.DeleteAll(); + _patientLogic.DeleteAll(); + MessageBox.Show("Все данные успешно удалены", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка получения модели приема"); + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + public void GenerateRandomDatabaseData() + { + int specsCount = 100; + int diagnosesCount = 100; + int doctorsCount = 100; + int patientsCount = 100; + int visitsCount = 100; + + double avgInsertSpecsTimer = 0; + double avgInsertDiagnosesTimer = 0; + double avgInsertDoctorsTimer = 0; + double avgInsertPatientsTimer = 0; + double avgInsertVisitsTimer = 0; + double temp = 0; + + Random rnd = new(); + + for (int i = 0; i < specsCount; i++) + { + _specLogic.Create(new Specialization + { + Name = i.ToString(), + IsPediatric = Convert.ToBoolean(rnd.Next(2)), + IsTherapeutic = Convert.ToBoolean(rnd.Next(2)) + }, out temp); + avgInsertSpecsTimer += temp; + } + avgInsertSpecsTimer /= specsCount; + + var specs = _specLogic.ReadList(); + + for (int i = 0; i < diagnosesCount; i++) + { + _diagnoseLogic.Create(new Diagnose + { + Name = i.ToString() + }, out temp); + avgInsertDiagnosesTimer += temp; + } + avgInsertDiagnosesTimer /= diagnosesCount; + + var diagnoses = _diagnoseLogic.ReadList(); + + for (int i = 0; i < doctorsCount; i++) + { + _doctorLogic.Create(new Doctor { + Name = i.ToString(), + Surname = i.ToString(), + Patronymic = i.ToString(), + PhoneNumber = i.ToString(), + SpecializationId = specs[rnd.Next(specs.Count)].Id + }, out temp); + avgInsertDoctorsTimer += temp; + } + + avgInsertDoctorsTimer /= doctorsCount; + + var doctors = _doctorLogic.ReadList(); + + for (int i = 0; i < patientsCount; i++) + { + _patientLogic.Create(new Patient { + Name = i.ToString(), + Surname = i.ToString(), + Patronymic = i.ToString(), + PhoneNumber = i.ToString(), + Birthday = new DateTime(2021, 12, 21), + Gender = rnd.Next(2) == 0 ? "М" : "Ж", + Height = rnd.Next(100, 250), + Weight = rnd.Next(50, 100) + }, out temp); + avgInsertPatientsTimer += temp; + } + + avgInsertPatientsTimer /= patientsCount; + var patients = _patientLogic.ReadList(); + + for (int i = 0; i < visitsCount; i++) + { + _visitLogic.Create(new Visit { + Date = new DateOnly(2021, 12, 12), + Time = new TimeOnly(12, 34), + PatientId = patients[rnd.Next(patients.Count)].Id, + DoctorId = doctors[rnd.Next(doctors.Count)].Id, + DiagnoseId = diagnoses[rnd.Next(diagnoses.Count)].Id, + Comment = "iusnefiuesnfes yf ey fiuewfwe fhweiufiuefiuweh fwehf uewyiufwe fuewoiuf oweyiuf weuif ioewfuyewuif yweufoiwefuywef" + }, out temp); + avgInsertVisitsTimer += temp; + } + + avgInsertVisitsTimer /= visitsCount; + + MessageBox.Show( + "Данные успешно сгенерированы!\n\n" + + "Среднее время вставки:\n" + + $"Специализации: {specsCount} шт : {avgInsertSpecsTimer} мск\n" + + $"Диагнозы: {diagnosesCount} шт : {avgInsertDiagnosesTimer} мск\n" + + $"Врачи: {doctorsCount} шт : {avgInsertDoctorsTimer} мск\n" + + $"Пациенты: {patientsCount} шт : {avgInsertPatientsTimer} мск\n" + + $"Приемы: {visitsCount} шт : {avgInsertVisitsTimer} мск\n", + "Успех", + MessageBoxButtons.OK, + MessageBoxIcon.Information); + } } }