From 699681488885524c8db3c4db113762edc63806b7 Mon Sep 17 00:00:00 2001 From: "DESKTOP-GENO133\\IvanPlex" Date: Mon, 12 Feb 2024 15:04:02 -0700 Subject: [PATCH] added backend for storing extra fields. --- Controllers/HomeController.cs | 27 ++++++- Controllers/MigrationController.cs | 43 ++++++++++- .../Litedb/ExtraFieldDataAccess.cs | 30 ++++++++ .../Postgres/ExtraFieldDataAccess.cs | 75 +++++++++++++++++++ External/Interfaces/IExtraFieldDataAccess.cs | 10 +++ Models/RecordExtraField.cs | 11 +++ Program.cs | 2 + 7 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 External/Implementations/Litedb/ExtraFieldDataAccess.cs create mode 100644 External/Implementations/Postgres/ExtraFieldDataAccess.cs create mode 100644 External/Interfaces/IExtraFieldDataAccess.cs create mode 100644 Models/RecordExtraField.cs diff --git a/Controllers/HomeController.cs b/Controllers/HomeController.cs index 9f37207..3079415 100644 --- a/Controllers/HomeController.cs +++ b/Controllers/HomeController.cs @@ -17,18 +17,20 @@ namespace CarCareTracker.Controllers private readonly IUserLogic _userLogic; private readonly IFileHelper _fileHelper; private readonly IConfigHelper _config; - - public HomeController(ILogger logger, + private readonly IExtraFieldDataAccess _extraFieldDataAccess; + public HomeController(ILogger logger, IVehicleDataAccess dataAccess, IUserLogic userLogic, IConfigHelper configuration, - IFileHelper fileHelper) + IFileHelper fileHelper, + IExtraFieldDataAccess extraFieldDataAccess) { _logger = logger; _dataAccess = dataAccess; _config = configuration; _userLogic = userLogic; _fileHelper = fileHelper; + _extraFieldDataAccess = extraFieldDataAccess; } private int GetUserID() { @@ -68,7 +70,24 @@ namespace CarCareTracker.Controllers { return View(); } - + public IActionResult GetExtraFieldsModal(int importMode = 0) + { + var recordExtraFields = _extraFieldDataAccess.GetExtraFieldsById(importMode); + return PartialView("_ExtraFields", recordExtraFields); + } + public IActionResult UpdateExtraFields(RecordExtraField record) + { + try + { + var result = _extraFieldDataAccess.SaveExtraFields(record); + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + } + var recordExtraFields = _extraFieldDataAccess.GetExtraFieldsById(record.Id); + return PartialView("_ExtraFields", recordExtraFields); + } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { diff --git a/Controllers/MigrationController.cs b/Controllers/MigrationController.cs index aa5c304..b97f39d 100644 --- a/Controllers/MigrationController.cs +++ b/Controllers/MigrationController.cs @@ -52,7 +52,8 @@ namespace CarCareTracker.Controllers "CREATE TABLE IF NOT EXISTS app.userrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, username TEXT not null, emailaddress TEXT not null, password TEXT not null, isadmin BOOLEAN)", "CREATE TABLE IF NOT EXISTS app.tokenrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, body TEXT not null, emailaddress TEXT not null)", "CREATE TABLE IF NOT EXISTS app.userconfigrecords (id INT primary key, data jsonb not null)", - "CREATE TABLE IF NOT EXISTS app.useraccessrecords (userId INT, vehicleId INT, PRIMARY KEY(userId, vehicleId))" + "CREATE TABLE IF NOT EXISTS app.useraccessrecords (userId INT, vehicleId INT, PRIMARY KEY(userId, vehicleId))", + "CREATE TABLE IF NOT EXISTS app.extrafields (id INT primary key, data jsonb not null)" }; foreach(string cmd in cmds) { @@ -97,6 +98,8 @@ namespace CarCareTracker.Controllers var tokenrecords = new List(); var userconfigrecords = new List(); var useraccessrecords = new List(); + + var extrafields = new List(); #region "Part1" string cmd = $"SELECT data FROM app.vehicles"; using (var ctext = pgDataSource.CreateCommand(cmd)) @@ -396,6 +399,25 @@ namespace CarCareTracker.Controllers }; } #endregion + #region "Part5" + cmd = $"SELECT data FROM app.extrafields"; + using (var ctext = pgDataSource.CreateCommand(cmd)) + { + using (NpgsqlDataReader reader = ctext.ExecuteReader()) + while (reader.Read()) + { + extrafields.Add(System.Text.Json.JsonSerializer.Deserialize(reader["data"] as string)); + } + } + foreach (var record in extrafields) + { + using (var db = new LiteDatabase(fullFileName)) + { + var table = db.GetCollection("extrafields"); + table.Upsert(record); + }; + } + #endregion var destFilePath = $"{fullFolderPath}.zip"; ZipFile.CreateFromDirectory(fullFolderPath, destFilePath); return Json(new OperationResponse { Success = true, Message = $"/{tempFolder}.zip" }); @@ -441,6 +463,8 @@ namespace CarCareTracker.Controllers var tokenrecords = new List(); var userconfigrecords = new List(); var useraccessrecords = new List(); + + var extrafields = new List(); #region "Part1" using (var db = new LiteDatabase(fullFileName)) { @@ -704,6 +728,23 @@ namespace CarCareTracker.Controllers } } #endregion + #region "Part5" + using (var db = new LiteDatabase(fullFileName)) + { + var table = db.GetCollection("extrafields"); + extrafields = table.FindAll().ToList(); + }; + foreach (var record in extrafields) + { + string cmd = $"INSERT INTO app.extrafields (id, data) VALUES(@id, CAST(@data AS jsonb))"; + using (var ctext = pgDataSource.CreateCommand(cmd)) + { + ctext.Parameters.AddWithValue("id", record.Id); + ctext.Parameters.AddWithValue("data", System.Text.Json.JsonSerializer.Serialize(record)); + ctext.ExecuteNonQuery(); + } + } + #endregion return Json(new OperationResponse { Success = true, Message = "Data Imported Successfully" }); } catch (Exception ex) diff --git a/External/Implementations/Litedb/ExtraFieldDataAccess.cs b/External/Implementations/Litedb/ExtraFieldDataAccess.cs new file mode 100644 index 0000000..c55d410 --- /dev/null +++ b/External/Implementations/Litedb/ExtraFieldDataAccess.cs @@ -0,0 +1,30 @@ +using CarCareTracker.External.Interfaces; +using CarCareTracker.Helper; +using CarCareTracker.Models; +using LiteDB; + +namespace CarCareTracker.External.Implementations +{ + public class ExtraFieldDataAccess: IExtraFieldDataAccess + { + private static string dbName = StaticHelper.DbName; + private static string tableName = "extrafields"; + public RecordExtraField GetExtraFieldsById(int importMode) + { + using (var db = new LiteDatabase(dbName)) + { + var table = db.GetCollection(tableName); + return table.FindById(importMode) ?? new RecordExtraField(); + }; + } + public bool SaveExtraFields(RecordExtraField record) + { + using (var db = new LiteDatabase(dbName)) + { + var table = db.GetCollection(tableName); + table.Upsert(record); + return true; + }; + } + } +} diff --git a/External/Implementations/Postgres/ExtraFieldDataAccess.cs b/External/Implementations/Postgres/ExtraFieldDataAccess.cs new file mode 100644 index 0000000..a5d930f --- /dev/null +++ b/External/Implementations/Postgres/ExtraFieldDataAccess.cs @@ -0,0 +1,75 @@ +using CarCareTracker.External.Interfaces; +using CarCareTracker.Models; +using Npgsql; +using System.Text.Json; + +namespace CarCareTracker.External.Implementations +{ + public class PGExtraFieldDataAccess : IExtraFieldDataAccess + { + private NpgsqlDataSource pgDataSource; + private readonly ILogger _logger; + private static string tableName = "extrafields"; + public PGExtraFieldDataAccess(IConfiguration config, ILogger logger) + { + pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]); + + _logger = logger; + try + { + //create table if not exist. + string initCMD = $"CREATE TABLE IF NOT EXISTS app.{tableName} (id INT primary key, data jsonb not null)"; + using (var ctext = pgDataSource.CreateCommand(initCMD)) + { + ctext.ExecuteNonQuery(); + } + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + } + } + public RecordExtraField GetExtraFieldsById(int importMode) + { + try + { + string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id"; + var results = new RecordExtraField(); + using (var ctext = pgDataSource.CreateCommand(cmd)) + { + ctext.Parameters.AddWithValue("id", importMode); + using (NpgsqlDataReader reader = ctext.ExecuteReader()) + while (reader.Read()) + { + RecordExtraField result = JsonSerializer.Deserialize(reader["data"] as string); + results = result; + } + } + return results; + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + return new RecordExtraField(); + } + } + public bool SaveExtraFields(RecordExtraField record) + { + try + { + string cmd = $"INSERT INTO app.{tableName} (id, data) VALUES(@id, CAST(@data AS jsonb))"; + using (var ctext = pgDataSource.CreateCommand(cmd)) + { + ctext.Parameters.AddWithValue("id", record.Id); + ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record)); + return ctext.ExecuteNonQuery() > 0; + } + } + catch (Exception ex) + { + _logger.LogError(ex.Message); + return false; + } + } + } +} diff --git a/External/Interfaces/IExtraFieldDataAccess.cs b/External/Interfaces/IExtraFieldDataAccess.cs new file mode 100644 index 0000000..1f69df7 --- /dev/null +++ b/External/Interfaces/IExtraFieldDataAccess.cs @@ -0,0 +1,10 @@ +using CarCareTracker.Models; + +namespace CarCareTracker.External.Interfaces +{ + public interface IExtraFieldDataAccess + { + public RecordExtraField GetExtraFieldsById(int importMode); + public bool SaveExtraFields(RecordExtraField record); + } +} diff --git a/Models/RecordExtraField.cs b/Models/RecordExtraField.cs new file mode 100644 index 0000000..68eb9a3 --- /dev/null +++ b/Models/RecordExtraField.cs @@ -0,0 +1,11 @@ +namespace CarCareTracker.Models +{ + public class RecordExtraField + { + /// + /// Corresponds to int value of ImportMode enum + /// + public int Id { get; set; } + public List ExtraFields { get; set; } = new List(); + } +} diff --git a/Program.cs b/Program.cs index 9c8a48a..169a9a8 100644 --- a/Program.cs +++ b/Program.cs @@ -31,6 +31,7 @@ if (!string.IsNullOrWhiteSpace(builder.Configuration["POSTGRES_CONNECTION"])){ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); } else { @@ -50,6 +51,7 @@ else builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); } //configure helpers