From 6ab3f5c52bcb5f88015d33cad398584fe9f42647 Mon Sep 17 00:00:00 2001 From: Eric Nguyen Date: Sat, 9 Dec 2023 10:58:55 +0700 Subject: [PATCH] Fix repodb npgsql connection cannot insert / update guid value --- .../mix.portal/Controllers/MixDbController.cs | 12 +++---- .../Repositories/MixRepoDbRepository.cs | 33 +++++++++++++++---- .../mix.repodb/Services/MixDbDataService.cs | 4 +-- .../mix.repodb/Services/MixDbService.cs | 27 ++++++++------- 4 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/modules/mix.portal/Controllers/MixDbController.cs b/src/modules/mix.portal/Controllers/MixDbController.cs index a0c65e624..76b71ec47 100644 --- a/src/modules/mix.portal/Controllers/MixDbController.cs +++ b/src/modules/mix.portal/Controllers/MixDbController.cs @@ -173,7 +173,7 @@ public async Task Import([FromForm] IFormFile file) lstDto.Add(await MixDbHelper.ParseImportDtoToEntityAsync(item, _mixDb.Columns, CurrentTenant.Id, _idService.GetClaim(User, MixClaims.Username))); } - var result = await _repository.InsertManyAsync(lstDto); + var result = await _repository.InsertManyAsync(lstDto, _mixDb); return Ok(result); } @@ -221,7 +221,7 @@ public async Task> UpdatePriority(string dbName, int id, [ foreach (var item in query.OrderBy(m => m[PriorityFieldName])) { item.Priority = start; - await _repository.UpdateAsync(item); + await _repository.UpdateAsync(item, _mixDb); start++; } @@ -230,7 +230,7 @@ public async Task> UpdatePriority(string dbName, int id, [ data[PriorityFieldName] = start; } - await _repository.UpdateAsync(data); + await _repository.UpdateAsync(data, _mixDb); return Ok(); } @@ -354,7 +354,7 @@ public async Task> Create(JObject dto) { JObject obj = await MixDbHelper.ParseDtoToEntityAsync(dto, _mixDb.Columns, CurrentTenant.Id, _idService.GetClaim(User, MixClaims.Username)); string username = _idService.GetClaim(User, MixClaims.Username); - var id = await _repository.InsertAsync(obj); + var id = await _repository.InsertAsync(obj, _mixDb); var resp = await _repository.GetSingleAsync(id); var result = resp != null ? ReflectionHelper.ParseObject(resp) : obj; QueueService.PushQueue(CurrentTenant.Id, MixQueueTopics.MixBackgroundTasks, MixQueueActions.MixDbEvent, @@ -368,7 +368,7 @@ public async Task> Update(int id, [FromBody] JObject dto) { JObject obj = await MixDbHelper.ParseDtoToEntityAsync(dto, _mixDb.Columns, CurrentTenant.Id, _idService.GetClaim(User, MixClaims.Username)); string username = _idService.GetClaim(User, MixClaims.Username); - var data = await _repository.UpdateAsync(obj); + var data = await _repository.UpdateAsync(obj, _mixDb); if (data != null) { var result = await _mixDbService.GetById(_tableName, id, true); @@ -479,7 +479,7 @@ private async Task PatchHandler(JObject objDto, CancellationToken cancellationTo } } - await _repository.UpdateAsync(objDto); + await _repository.UpdateAsync(objDto, _mixDb); QueueService.PushQueue(CurrentTenant.Id, MixQueueTopics.MixBackgroundTasks, MixQueueActions.MixDbEvent, new MixDbEventCommand(username, "PATCH", _tableName, objDto)); } diff --git a/src/platform/mix.repodb/Repositories/MixRepoDbRepository.cs b/src/platform/mix.repodb/Repositories/MixRepoDbRepository.cs index 986d7d848..81f7b4730 100644 --- a/src/platform/mix.repodb/Repositories/MixRepoDbRepository.cs +++ b/src/platform/mix.repodb/Repositories/MixRepoDbRepository.cs @@ -2,6 +2,7 @@ using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.Options; using Mix.Constant.Constants; using Mix.Constant.Enums; using Mix.Database.Entities.Cms; @@ -14,6 +15,7 @@ using Mix.Heart.UnitOfWork; using Mix.RepoDb.Models; using Mix.RepoDb.Services; +using Mix.RepoDb.ViewModels; using Mix.Service.Services; using Mix.Shared.Dtos; using Mix.Shared.Models; @@ -360,12 +362,13 @@ private Operation ParseMixOperator(SearchQueryField field) } } - public async Task InsertAsync(JObject obj) + public async Task InsertAsync(JObject obj, RepoDbMixDatabaseViewModel mixDb) { try { BeginTransaction(); - var dicObj = obj.ToObject>(); + Dictionary dicObj = ParseDictionary(obj, mixDb); + var fields = dicObj!.Keys.Select(m => new Field(m)).ToList(); var result = await _connection.InsertAsync( _tableName, @@ -383,7 +386,8 @@ public async Task InsertAsync(JObject obj) } } - public async Task InsertManyAsync(List entities) + + public async Task InsertManyAsync(List entities, RepoDbMixDatabaseViewModel mixDb) { try { @@ -396,7 +400,7 @@ public async Task InsertAsync(JObject obj) foreach (var entity in entities) { - var dicObj = entity.ToObject>(); + var dicObj = ParseDictionary(entity, mixDb); if (dicObj != null) { dicObjs.Add(dicObj); @@ -445,7 +449,7 @@ public async Task InsertAsync(JObject obj) } } - public async Task UpdateAsync(JObject entity) + public async Task UpdateAsync(JObject entity, RepoDbMixDatabaseViewModel mixDb) { try { @@ -453,7 +457,7 @@ public async Task InsertAsync(JObject obj) int id = entity.Value("Id"); if (_connection.Exists(_tableName, new { Id = id }, transaction: _dbTransaction)) { - object obj = entity.ToObject>()!; + var obj = ParseDictionary(entity, mixDb); var cacheFolder = MixDbDataService.GetCacheFolder(_tableName); MixFileHelper.EmptyFolder($"{MixFolders.MixCacheFolder}/{cacheFolder}/{id}"); return await _connection.UpdateAsync(_tableName, obj, @@ -724,5 +728,22 @@ public void Dispose() _connection.Close(); } } + + private Dictionary ParseDictionary(JObject obj, RepoDbMixDatabaseViewModel mixDb) + { + var dicObj = obj.ToObject>(); + + // npgsql cannot auto parse from string to Guid + var guidCols = mixDb.Columns.Where(c => c.DataType == MixDataType.Guid).ToList(); + foreach (var item in guidCols) + { + var colTitle = item.SystemName.ToTitleCase(); + if (dicObj.ContainsKey(colTitle) && dicObj[colTitle] != null) + { + dicObj[colTitle] = Guid.Parse(dicObj[colTitle].ToString()!); + } + } + return dicObj; + } } } diff --git a/src/platform/mix.repodb/Services/MixDbDataService.cs b/src/platform/mix.repodb/Services/MixDbDataService.cs index f524943b0..a9635c75c 100644 --- a/src/platform/mix.repodb/Services/MixDbDataService.cs +++ b/src/platform/mix.repodb/Services/MixDbDataService.cs @@ -193,7 +193,7 @@ public async Task CreateData(string tableName, JObject data) { await InitRepository(tableName); var obj = await ParseDto(tableName, data); - return await _repository.InsertAsync(obj); + return await _repository.InsertAsync(obj, _mixDb); } catch (MixException) { @@ -216,7 +216,7 @@ public async Task CreateData(string tableName, JObject data) { throw new MixException(MixErrorStatus.NotFound); } - return await _repository.UpdateAsync(obj); + return await _repository.UpdateAsync(obj, _mixDb); } catch (MixException) { diff --git a/src/platform/mix.repodb/Services/MixDbService.cs b/src/platform/mix.repodb/Services/MixDbService.cs index a5b437a76..d6b4720f1 100644 --- a/src/platform/mix.repodb/Services/MixDbService.cs +++ b/src/platform/mix.repodb/Services/MixDbService.cs @@ -638,21 +638,24 @@ private void InitBackupRepository(string databaseName) private async Task RestoreFromLocal(RepoDbMixDatabaseViewModel database) { - InitBackupRepository(database.SystemName); - var data = await _backupRepository.GetAllAsync(); - if (data is { Count: > 0 }) + if (File.Exists($"MixContent/Backup/backup_{database.SystemName}.sqlite")) { - var dbColumns = database.Columns.Select(c => c.SystemName.ToTitleCase()).Union(DefaultProperties).ToList(); - string insertQuery = $"INSERT INTO {database.SystemName} ({string.Join(',', dbColumns.Select(m => $"{_databaseConstant.BacktickOpen}{m}{_databaseConstant.BacktickClose}"))}) VALUES "; - List queries = new(); - foreach (var item in data) + InitBackupRepository(database.SystemName); + var data = await _backupRepository.GetAllAsync(); + if (data is { Count: > 0 }) { - queries.Add(GetInsertQuery(item, dbColumns)); + var dbColumns = database.Columns.Select(c => c.SystemName.ToTitleCase()).Union(DefaultProperties).ToList(); + string insertQuery = $"INSERT INTO {database.SystemName} ({string.Join(',', dbColumns.Select(m => $"{_databaseConstant.BacktickOpen}{m}{_databaseConstant.BacktickClose}"))}) VALUES "; + List queries = new(); + foreach (var item in data) + { + queries.Add(GetInsertQuery(item, dbColumns)); + } + insertQuery += string.Join(',', queries); + _repository.InitTableName(database.SystemName); + var result = await _repository.ExecuteCommand(insertQuery); + return result >= 0; } - insertQuery += string.Join(',', queries); - _repository.InitTableName(database.SystemName); - var result = await _repository.ExecuteCommand(insertQuery); - return result >= 0; } return true; }