From 9dc3fe3a2fa4de40f14b1b22128878257e3a8a9f Mon Sep 17 00:00:00 2001 From: "ns.potapov" Date: Wed, 8 May 2024 11:09:59 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=20=D0=B2=D1=81=D0=B5=20=D1=85=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=BB=D0=B8=D1=89=D0=B0=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B5=D0=B9=20=D0=91=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Models/Patient.cs | 2 +- .../AbstractPostgresqlStorage.cs | 114 ++++++++++++++++-- .../Storages/DiagnosesStorage.cs | 42 ++----- .../Storages/DoctorsStorage.cs | 63 +++------- .../Storages/PatientStorage.cs | 45 +++++++ .../Storages/SpecializationStorage.cs | 36 ++++++ .../MedicalPostgresqlDatabase/VisitStorage.cs | 38 ++++++ 7 files changed, 251 insertions(+), 89 deletions(-) create mode 100644 Medical/MedicalPostgresqlDatabase/Storages/PatientStorage.cs create mode 100644 Medical/MedicalPostgresqlDatabase/Storages/SpecializationStorage.cs create mode 100644 Medical/MedicalPostgresqlDatabase/VisitStorage.cs diff --git a/Medical/MedicalDatabaseContracts/Models/Patient.cs b/Medical/MedicalDatabaseContracts/Models/Patient.cs index 51e8243..3ce57b5 100644 --- a/Medical/MedicalDatabaseContracts/Models/Patient.cs +++ b/Medical/MedicalDatabaseContracts/Models/Patient.cs @@ -7,7 +7,7 @@ namespace MedicalDatabaseContracts.Models [DisplayName("Пол")] public char Gender { get; set; } [DisplayName("Дата рождения")] - public DateOnly Birthday { get; set; } + public DateTime Birthday { get; set; } [DisplayName("Вес, кг")] public int Weight { get; set; } [DisplayName("Рост, см")] diff --git a/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs b/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs index 9d5f33a..4f3a767 100644 --- a/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs +++ b/Medical/MedicalPostgresqlDatabase/AbstractPostgresqlStorage.cs @@ -1,5 +1,6 @@ using MedicalDatabaseContracts; using MedicalDatabaseContracts.Models; +using Microsoft.Extensions.Logging; using Npgsql; using System.Diagnostics; @@ -7,21 +8,31 @@ namespace MedicalPostgresqlDatabase { public abstract class AbstractPostgresqlStorage : IStorage where T : AbstractModel { + protected ILogger _logger; protected readonly string TABLE_NAME; protected readonly string PRIMARY_KEY_COLUMN_NAME; + protected readonly string PRIMARY_KEY_SEQUENCE_NAME; - protected AbstractPostgresqlStorage(string tableName, string primaryKeyColumnName) + protected AbstractPostgresqlStorage( + ILogger> logger, + string tableName, + string primaryKeyColumnName, + string primary_key_sequence_name) { + _logger = logger; TABLE_NAME = tableName; PRIMARY_KEY_COLUMN_NAME = primaryKeyColumnName; + PRIMARY_KEY_SEQUENCE_NAME = primary_key_sequence_name; } protected abstract T CreateEntityFromReader(NpgsqlDataReader reader); + protected abstract Dictionary GetEntityAttributesDictionary(T item); + public virtual void Delete(int id) { - long elapsedMilliseconds; - Delete(id, out elapsedMilliseconds); + long _; + Delete(id, out _); } public virtual void Delete(int id, out long elapsedMilliseconds) { @@ -37,8 +48,8 @@ namespace MedicalPostgresqlDatabase } public virtual T? Get(int id) { - long elapsedMilliseconds; - return Get(id, out elapsedMilliseconds); + long _; + return Get(id, out _); } public virtual T? Get(int id, out long elapsedMilliseconds) { @@ -59,8 +70,8 @@ namespace MedicalPostgresqlDatabase } public virtual List GetAll() { - long elapsedMilliseconds; - return GetAll(out elapsedMilliseconds); + long _; + return GetAll(out _); } public virtual List GetAll(out long elapsedMilliseconds) { @@ -81,16 +92,93 @@ namespace MedicalPostgresqlDatabase } public virtual void Insert(T item) { - long elapsedMilliseconds; - Insert(item, out elapsedMilliseconds); + long _; + Insert(item, out _); + } + public virtual void Insert(T item, out long elapsedMilliseconds) + { + using var connection = GetConnection(); + connection.Open(); + var dict = GetEntityAttributesDictionary(item); + + string namesString = ""; + string valuesString = ""; + foreach (var key in dict.Keys) + { + namesString = string.Join(", ", namesString, $"{key}"); + if (key == PRIMARY_KEY_COLUMN_NAME) + valuesString = string.Join(", ", valuesString, $"nextval('{PRIMARY_KEY_SEQUENCE_NAME}')"); + else + valuesString = string.Join(", ", valuesString, $"@{key}"); + } + namesString = $"({namesString})"; + valuesString += $"({valuesString})"; + + + string[] queryBuilder = { + "INSERT INTO", + TABLE_NAME, + namesString, + "VALUES", + valuesString + }; + + using var cmd = new NpgsqlCommand(string.Join(' ', queryBuilder), connection); + + foreach (var key in dict.Keys) + { + cmd.Parameters.AddWithValue($"@{key}", dict[key]); + } + Stopwatch stopwatch = new(); + stopwatch.Start(); + cmd.ExecuteNonQuery(); + stopwatch.Stop(); + elapsedMilliseconds = stopwatch.ElapsedMilliseconds; } - public abstract void Insert(T item, out long elapsedMilliseconds); public virtual void Update(T item) { - long elapsedMilliseconds; - Update(item, out elapsedMilliseconds); + long _; + Update(item, out _); + } + public virtual void Update(T item, out long elapsedMilliseconds) + { + using var connection = GetConnection(); + connection.Open(); + + var dict = GetEntityAttributesDictionary(item); + + string setString = ""; + foreach (var key in dict.Keys) + { + if (key != PRIMARY_KEY_COLUMN_NAME) + setString = string.Join(", ", setString, $"{key} = @{key}"); + } + setString = $"({setString})"; + + string[] queryBuilder = { + "UPDATE", + TABLE_NAME, + "SET", + setString, + "VALUES", + setString, + "WHERE", + $"{PRIMARY_KEY_COLUMN_NAME} = @{PRIMARY_KEY_COLUMN_NAME}" + }; + + using var cmd = new NpgsqlCommand(string.Join(' ', queryBuilder), connection); + + foreach (var key in dict.Keys) + { + cmd.Parameters.AddWithValue($"@{key}", dict[key]); + } + + Stopwatch stopwatch = new(); + stopwatch.Start(); + cmd.ExecuteNonQuery(); + stopwatch.Stop(); + elapsedMilliseconds = stopwatch.ElapsedMilliseconds; } - public abstract void Update(T item, out long elapsedMilliseconds); protected NpgsqlConnection GetConnection() { diff --git a/Medical/MedicalPostgresqlDatabase/Storages/DiagnosesStorage.cs b/Medical/MedicalPostgresqlDatabase/Storages/DiagnosesStorage.cs index 9c64896..1dd3691 100644 --- a/Medical/MedicalPostgresqlDatabase/Storages/DiagnosesStorage.cs +++ b/Medical/MedicalPostgresqlDatabase/Storages/DiagnosesStorage.cs @@ -1,52 +1,32 @@ using MedicalDatabaseContracts.Models; using Microsoft.Extensions.Logging; using Npgsql; +using System.Data; using System.Diagnostics; namespace MedicalPostgresqlDatabase.Storages { public class DiagnosesStorage : AbstractPostgresqlStorage { - private ILogger _logger; - public DiagnosesStorage(ILogger logger) : base("diagnoses", "diagnose_id") - { - _logger = logger; - } + public DiagnosesStorage(ILogger logger) : base(logger, "diagnoses", "diagnose_id", "diagnoses_id_seq") { } protected override Diagnose CreateEntityFromReader(NpgsqlDataReader reader) { return new Diagnose { - Id = Convert.ToInt32(reader.GetOrdinal(PRIMARY_KEY_COLUMN_NAME)), - Name = Convert.ToString(reader.GetOrdinal("name")), + Id = Convert.ToInt32(reader.GetValue(PRIMARY_KEY_COLUMN_NAME)), + Name = Convert.ToString(reader.GetValue("name")), }; } - public override void Insert(Diagnose item, out long elapsedMilliseconds) + protected override Dictionary GetEntityAttributesDictionary(Diagnose item) { - using var connection = GetConnection(); - connection.Open(); - using var cmd = new NpgsqlCommand($"INSERT INTO diagnoses ({PRIMARY_KEY_COLUMN_NAME}, name) VALUES ((nextval('diagnoses_id_seq')), @name)", connection); - cmd.Parameters.AddWithValue("@name", item.Name); - Stopwatch stopwatch = new(); - stopwatch.Start(); - cmd.ExecuteNonQuery(); - stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; - } - - public override void Update(Diagnose item, out long elapsedMilliseconds) - { - using var connection = GetConnection(); - connection.Open(); - using var cmd = new NpgsqlCommand($"UPDATE diagnoses SET name = @name WHERE {PRIMARY_KEY_COLUMN_NAME} = @id", connection); - cmd.Parameters.AddWithValue("@id", item.Id); - cmd.Parameters.AddWithValue("@name", item.Name); - Stopwatch stopwatch = new(); - stopwatch.Start(); - cmd.ExecuteNonQuery(); - stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + var dict = new Dictionary + { + { PRIMARY_KEY_COLUMN_NAME, item.Id.ToString() }, + { "name", item.Name }, + }; + return dict; } } } diff --git a/Medical/MedicalPostgresqlDatabase/Storages/DoctorsStorage.cs b/Medical/MedicalPostgresqlDatabase/Storages/DoctorsStorage.cs index 339d376..f3ce877 100644 --- a/Medical/MedicalPostgresqlDatabase/Storages/DoctorsStorage.cs +++ b/Medical/MedicalPostgresqlDatabase/Storages/DoctorsStorage.cs @@ -1,64 +1,39 @@ using MedicalDatabaseContracts.Models; using Microsoft.Extensions.Logging; using Npgsql; -using System.Diagnostics; +using System.Data; namespace MedicalPostgresqlDatabase.Storages { public class DoctorsStorage : AbstractPostgresqlStorage { - private ILogger _logger; - public DoctorsStorage(ILogger logger) : base("doctors", "doctor_id") - { - _logger = logger; - } + public DoctorsStorage(ILogger logger) : base(logger, "doctors", "doctor_id", "doctors_id_seq") { } protected override Doctor CreateEntityFromReader(NpgsqlDataReader reader) { return new Doctor { - Id = Convert.ToInt32(reader.GetOrdinal(PRIMARY_KEY_COLUMN_NAME)), - Name = Convert.ToString(reader.GetOrdinal("name")), - Surname = Convert.ToString(reader.GetOrdinal("surname")), - Patronymic = Convert.ToString(reader.GetOrdinal("patronymic")), - PhoneNumber = Convert.ToString(reader.GetOrdinal("phone_number")), - SpecializationId = Convert.ToInt32(reader.GetOrdinal("specializaton_id")) + Id = Convert.ToInt32(reader.GetValue(PRIMARY_KEY_COLUMN_NAME)), + Name = Convert.ToString(reader.GetValue("name")), + Surname = Convert.ToString(reader.GetValue("surname")), + Patronymic = Convert.ToString(reader.GetValue("patronymic")), + PhoneNumber = Convert.ToString(reader.GetValue("phone_number")), + SpecializationId = Convert.ToInt32(reader.GetValue("specializaton_id")) }; } - public override void Insert(Doctor item, out long elapsedMilliseconds) + protected override Dictionary GetEntityAttributesDictionary(Doctor item) { - using var connection = GetConnection(); - connection.Open(); - using var cmd = new NpgsqlCommand($"INSERT INTO doctors ({PRIMARY_KEY_COLUMN_NAME}, name, surname, patronymic, phone_number, specialization_id) VALUES ((nextval('doctors_id_seq')), @name, @surname, @patronymic, @phone_number, @specialization_id)", connection); - cmd.Parameters.AddWithValue("@name", item.Name); - cmd.Parameters.AddWithValue("@surname", item.Surname); - cmd.Parameters.AddWithValue("@patronymic", item.Patronymic); - cmd.Parameters.AddWithValue("@phone_number", item.PhoneNumber); - cmd.Parameters.AddWithValue("@specialization_id", item.SpecializationId); - Stopwatch stopwatch = new(); - stopwatch.Start(); - cmd.ExecuteNonQuery(); - stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; - } - - public override void Update(Doctor item, out long elapsedMilliseconds) - { - using var connection = GetConnection(); - connection.Open(); - using var cmd = new NpgsqlCommand($"UPDATE doctors SET name = @name, surname = @surname, patronymic = @patronymic, phone_number = @phone_number, specialization_id = @specialization_id, WHERE {PRIMARY_KEY_COLUMN_NAME} = @id", connection); ; - cmd.Parameters.AddWithValue("@id", item.Id); - cmd.Parameters.AddWithValue("@name", item.Name); - cmd.Parameters.AddWithValue("@surname", item.Surname); - cmd.Parameters.AddWithValue("@patronymic", item.Patronymic); - cmd.Parameters.AddWithValue("@phone_number", item.PhoneNumber); - cmd.Parameters.AddWithValue("@specialization_id", item.SpecializationId); - Stopwatch stopwatch = new(); - stopwatch.Start(); - cmd.ExecuteNonQuery(); - stopwatch.Stop(); - elapsedMilliseconds = stopwatch.ElapsedMilliseconds; + var dict = new Dictionary + { + { PRIMARY_KEY_COLUMN_NAME, item.Id.ToString() }, + { "name", item.Name }, + { "surname", item.Surname }, + { "patronymic", item.Patronymic }, + { "phone_number", item.PhoneNumber }, + { "specialization_id", item.SpecializationId.ToString() } + }; + return dict; } } } diff --git a/Medical/MedicalPostgresqlDatabase/Storages/PatientStorage.cs b/Medical/MedicalPostgresqlDatabase/Storages/PatientStorage.cs new file mode 100644 index 0000000..a18134f --- /dev/null +++ b/Medical/MedicalPostgresqlDatabase/Storages/PatientStorage.cs @@ -0,0 +1,45 @@ +using MedicalDatabaseContracts.Models; +using Microsoft.Extensions.Logging; +using Npgsql; +using System.Data; + +namespace MedicalPostgresqlDatabase.Storages +{ + public class PatientStorage : AbstractPostgresqlStorage + { + public PatientStorage(ILogger logger) : base(logger, "patients", "patient_id", "patients_id_seq") { } + + protected override Patient CreateEntityFromReader(NpgsqlDataReader reader) + { + return new Patient + { + Id = Convert.ToInt32(reader.GetValue(PRIMARY_KEY_COLUMN_NAME)), + Name = Convert.ToString(reader.GetValue("name")), + Surname = Convert.ToString(reader.GetValue("surname")), + Patronymic = Convert.ToString(reader.GetValue("patronymic")), + PhoneNumber = Convert.ToString(reader.GetValue("phone_number")), + Gender = Convert.ToChar(reader.GetValue("gender")), + Birthday = Convert.ToDateTime(reader.GetValue("birthday")), + Weight = Convert.ToInt32(reader.GetValue("weight")), + Height = Convert.ToInt32(reader.GetValue("height")), + }; + } + + protected override Dictionary GetEntityAttributesDictionary(Patient item) + { + var dict = new Dictionary + { + { PRIMARY_KEY_COLUMN_NAME, item.Id.ToString() }, + { "name", item.Name }, + { "surname", item.Surname }, + { "patronymic", item.Patronymic }, + { "phone_number", item.PhoneNumber }, + { "gender", item.Gender.ToString() }, + { "birthday", item.Birthday.ToString() }, + { "weight", item.Weight.ToString() }, + { "height", item.Height.ToString() }, + }; + return dict; + } + } +} diff --git a/Medical/MedicalPostgresqlDatabase/Storages/SpecializationStorage.cs b/Medical/MedicalPostgresqlDatabase/Storages/SpecializationStorage.cs new file mode 100644 index 0000000..a8804ff --- /dev/null +++ b/Medical/MedicalPostgresqlDatabase/Storages/SpecializationStorage.cs @@ -0,0 +1,36 @@ +using MedicalDatabaseContracts; +using MedicalDatabaseContracts.Models; +using Microsoft.Extensions.Logging; +using Npgsql; +using System.Data; + +namespace MedicalPostgresqlDatabase.Storages +{ + public class SpecializationStorage : AbstractPostgresqlStorage + { + public SpecializationStorage(ILogger> logger) : base(logger, "specializations", "specialization_id", "specializations_id_seq") { } + + protected override Specialization CreateEntityFromReader(NpgsqlDataReader reader) + { + return new Specialization + { + Id = Convert.ToInt32(reader.GetValue(PRIMARY_KEY_COLUMN_NAME)), + Name = Convert.ToString(reader.GetValue("name")), + IsPediatric = Convert.ToBoolean(reader.GetValue("is_pediatric")), + IsTherapeutic = Convert.ToBoolean(reader.GetValue("is_therapeutic")), + }; + } + + protected override Dictionary GetEntityAttributesDictionary(Specialization item) + { + var dict = new Dictionary + { + { PRIMARY_KEY_COLUMN_NAME, item.Id.ToString() }, + { "name", item.Name }, + { "is_pediatric", item.IsPediatric.ToString() }, + { "is_therapeutic", item.IsTherapeutic.ToString() }, + }; + return dict; + } + } +} diff --git a/Medical/MedicalPostgresqlDatabase/VisitStorage.cs b/Medical/MedicalPostgresqlDatabase/VisitStorage.cs new file mode 100644 index 0000000..8b9b168 --- /dev/null +++ b/Medical/MedicalPostgresqlDatabase/VisitStorage.cs @@ -0,0 +1,38 @@ +using MedicalDatabaseContracts; +using MedicalDatabaseContracts.Models; +using Microsoft.Extensions.Logging; +using Npgsql; +using System.Data; + +namespace MedicalPostgresqlDatabase +{ + public class VisitStorage : AbstractPostgresqlStorage + { + public VisitStorage(ILogger> logger) : base(logger, "visits", "visit_id", "visits_id_seq") { } + + protected override Visit CreateEntityFromReader(NpgsqlDataReader reader) + { + return new Visit + { + Id = Convert.ToInt32(reader.GetValue(PRIMARY_KEY_COLUMN_NAME)), + PatientId = Convert.ToInt32(reader.GetValue("patient_id")), + DoctorId = Convert.ToInt32(reader.GetValue("doctor_id")), + DiagnoseId = Convert.ToInt32(reader.GetValue("diagnose_id")), + Comment = Convert.ToString(reader.GetValue("comment")), + }; + } + + protected override Dictionary GetEntityAttributesDictionary(Visit item) + { + var dict = new Dictionary + { + { PRIMARY_KEY_COLUMN_NAME, item.Id.ToString() }, + { "patient_id", item.PatientId.ToString() }, + { "doctor_id", item.DoctorId.ToString() }, + { "diagnose_id", item.DiagnoseId.ToString() }, + { "comment", item.Comment }, + }; + return dict; + } + } +}