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 | b55a980d665b5ab37f219b0dbcde09ecd23b0b75 (patch) | |
| tree | 5a2ee9b099b72f15df1384f6b095b2b9d301d587 | |
| parent | 4fe8d1c88cafd86950e41ae81b94c0d1790e7dfa (diff) | |
| download | crupest-b55a980d665b5ab37f219b0dbcde09ecd23b0b75.tar.gz crupest-b55a980d665b5ab37f219b0dbcde09ecd23b0b75.tar.bz2 crupest-b55a980d665b5ab37f219b0dbcde09ecd23b0b75.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); +    }  }  | 
