diff options
author | crupest <crupest@outlook.com> | 2022-12-14 15:58:41 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-12-20 20:32:53 +0800 |
commit | 94d39ea715ae81ef93e1bc289762b7500db197f9 (patch) | |
tree | 5a2ee9b099b72f15df1384f6b095b2b9d301d587 | |
parent | 799170d34c8b59116895f07328412c4b2236b39e (diff) | |
download | crupest-94d39ea715ae81ef93e1bc289762b7500db197f9.tar.gz crupest-94d39ea715ae81ef93e1bc289762b7500db197f9.tar.bz2 crupest-94d39ea715ae81ef93e1bc289762b7500db197f9.zip |
Develop secret api. v38
4 files changed, 97 insertions, 11 deletions
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs index 5d73002..796761e 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs @@ -4,7 +4,6 @@ using Dapper; namespace CrupestApi.Commons.Crud; -// TODO: Register this. public class CrudService<TEntity> : IDisposable where TEntity : class { protected readonly TableInfo _table; @@ -38,4 +37,10 @@ public class CrudService<TEntity> : IDisposable where TEntity : class { _dbConnection.Dispose(); } + + public List<TEntity> GetAll() + { + var result = _table.Select<TEntity>(_dbConnection, null); + return result; + } } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs index 29504f4..8854976 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs @@ -4,11 +4,21 @@ namespace CrupestApi.Commons.Crud; public static class CrudServiceCollectionExtensions { - public static IServiceCollection UseCrud(this IServiceCollection services) + public static IServiceCollection AddCrudCore(this IServiceCollection services) { services.TryAddSingleton<IDbConnectionFactory, SqliteConnectionFactory>(); services.TryAddSingleton<IColumnTypeProvider, ColumnTypeProvider>(); services.TryAddSingleton<ITableInfoFactory, TableInfoFactory>(); return services; } + + public static IServiceCollection AddCrud<TEntity>(this IServiceCollection services) where TEntity : class + { + AddCrudCore(services); + + services.TryAddScoped<CrudService<TEntity>>(); + services.TryAddScoped<EntityJsonHelper<TEntity>>(); + + return services; + } } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs index 70196d7..e9999af 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs @@ -2,4 +2,16 @@ namespace CrupestApi.Commons.Crud; public static class CrudWebApplicationExtensions { + public static WebApplication UseCrud<TEntity>(this WebApplication app, string path) where TEntity : class + { + app.MapGet(path, async (context) => + { + var crudService = context.RequestServices.GetRequiredService<CrudService<TEntity>>(); + var entityJsonHelper = context.RequestServices.GetRequiredService<EntityJsonHelper<TEntity>>(); + var allEntities = crudService.GetAll(); + await context.ResponseJsonAsync(allEntities.Select(e => entityJsonHelper.ConvertEntityToDictionary(e))); + }); + + return app; + } } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/EntityJsonHelper.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/EntityJsonHelper.cs index 7db843b..497c086 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/EntityJsonHelper.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/EntityJsonHelper.cs @@ -5,7 +5,6 @@ using Microsoft.Extensions.Options; namespace CrupestApi.Commons.Crud; -// TODO: Register this. /// <summary> /// Contains all you need to do with json. /// </summary> @@ -20,10 +19,8 @@ public class EntityJsonHelper<TEntity> where TEntity : class _jsonSerializerOptions = jsonSerializerOptions; } - public virtual Dictionary<string, object?> ConvertEntityToDictionary(object? entity, bool includeNonColumnProperties = false) + public virtual Dictionary<string, object?> ConvertEntityToDictionary(TEntity entity, bool includeNonColumnProperties = false) { - Debug.Assert(entity is null || entity is TEntity); - var result = new Dictionary<string, object?>(); foreach (var propertyInfo in _table.ColumnProperties) @@ -44,11 +41,9 @@ public class EntityJsonHelper<TEntity> where TEntity : class return result; } - public virtual string ConvertEntityToJson(object? entity) + public virtual string ConvertEntityToJson(TEntity entity, bool includeNonColumnProperties = false) { - Debug.Assert(entity is null || entity is TEntity); - - var dictionary = ConvertEntityToDictionary(entity); + var dictionary = ConvertEntityToDictionary(entity, includeNonColumnProperties); return JsonSerializer.Serialize(dictionary, _jsonSerializerOptions.CurrentValue); } @@ -93,9 +88,73 @@ public class EntityJsonHelper<TEntity> where TEntity : class return insertClause; } - public IInsertClause ConvertJsonToEntityForInsert(string json) + public IInsertClause ConvertJsonToInsertClauses(string json) { var document = JsonSerializer.Deserialize<JsonDocument>(json, _jsonSerializerOptions.CurrentValue)!; return ConvertJsonElementToInsertClauses(document.RootElement); } + + public IUpdateClause ConvertJsonElementToUpdateClause(JsonDocument json) + { + var updateClause = UpdateClause.Create(); + + if (json.RootElement.ValueKind != JsonValueKind.Object) + { + throw new UserException("The root element must be an object."); + } + + bool saveNull = false; + + if (json.RootElement.TryGetProperty("$saveNull", out var propertyElement)) + { + if (propertyElement.ValueKind is not JsonValueKind.True or JsonValueKind.False) + { + throw new UserException("$saveNull can only be true or false."); + } + + if (propertyElement.ValueKind is JsonValueKind.True) + { + saveNull = true; + } + } + + + foreach (var column in _table.PropertyColumns) + { + object? value = null; + + if (json.RootElement.TryGetProperty(column.ColumnName, out propertyElement)) + { + value = propertyElement.ValueKind switch + { + JsonValueKind.Null or JsonValueKind.Undefined => null, + JsonValueKind.Number => propertyElement.GetDouble(), + JsonValueKind.True => true, + JsonValueKind.False => false, + JsonValueKind.String => propertyElement.GetString(), + _ => throw new Exception($"Bad json value of property {column.ColumnName}.") + }; + + if (column.IsNoUpdate && (value is not null || saveNull)) + { + throw new UserException($"The property {column.ColumnName} is not updatable. You cannot specify its value."); + } + } + + if (value is null && !saveNull) + { + continue; + } + + updateClause.Add(column.ColumnName, value ?? DbNullValue.Instance); + } + + return updateClause; + } + + public IUpdateClause ConvertJsonToUpdateClause(string json) + { + var document = JsonSerializer.Deserialize<JsonDocument>(json, _jsonSerializerOptions.CurrentValue)!; + return ConvertJsonElementToUpdateClause(document); + } } |