diff options
author | crupest <crupest@outlook.com> | 2022-12-08 21:02:49 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-12-20 20:32:52 +0800 |
commit | 20989284d1884892b469e4824e1b8a41d6743bc2 (patch) | |
tree | f26880280ee81dabb7bbc876bdb475ed9f77bdeb /docker/crupest-api/CrupestApi/CrupestApi.Commons | |
parent | 62c92f97358e2a98271aaf11fdd5626e21cf4689 (diff) | |
download | crupest-20989284d1884892b469e4824e1b8a41d6743bc2.tar.gz crupest-20989284d1884892b469e4824e1b8a41d6743bc2.tar.bz2 crupest-20989284d1884892b469e4824e1b8a41d6743bc2.zip |
Develop secret api. v19
Diffstat (limited to 'docker/crupest-api/CrupestApi/CrupestApi.Commons')
3 files changed, 155 insertions, 9 deletions
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs index 14960c7..70fdbfd 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs @@ -1,15 +1,67 @@ using System.Data; using System.Diagnostics; +using System.Globalization; +using System.Text.Json; using System.Text.Json.Serialization; namespace CrupestApi.Commons.Crud; -// TODO: Implement this. public interface IColumnTypeInfo { + public static IColumnTypeInfo IntColumnTypeInfo { get; } = new SimpleColumnTypeInfo<int>(); + public static IColumnTypeInfo ShortColumnTypeInfo { get; } = new SimpleColumnTypeInfo<short>(); + public static IColumnTypeInfo SByteColumnTypeInfo { get; } = new SimpleColumnTypeInfo<sbyte>(); + public static IColumnTypeInfo LongColumnTypeInfo { get; } = new SimpleColumnTypeInfo<long>(); + public static IColumnTypeInfo FloatColumnTypeInfo { get; } = new SimpleColumnTypeInfo<float>(); + public static IColumnTypeInfo DoubleColumnTypeInfo { get; } = new SimpleColumnTypeInfo<double>(); + public static IColumnTypeInfo StringColumnTypeInfo { get; } = new SimpleColumnTypeInfo<string>(); + public static IColumnTypeInfo BytesColumnTypeInfo { get; } = new SimpleColumnTypeInfo<byte[]>(); + public static IColumnTypeInfo DateTimeColumnTypeInfo { get; } = new DateTimeColumnTypeInfo(); + Type ClrType { get; } Type DatabaseClrType { get; } - DbType DbType { get; } + DbType DbType + { + get + { + if (DatabaseClrType == typeof(int)) + { + return DbType.Int32; + } + else if (DatabaseClrType == typeof(long)) + { + return DbType.Int64; + } + else if (DatabaseClrType == typeof(short)) + { + return DbType.Int16; + } + else if (DatabaseClrType == typeof(sbyte)) + { + return DbType.SByte; + } + else if (DatabaseClrType == typeof(double)) + { + return DbType.Double; + } + else if (DatabaseClrType == typeof(float)) + { + return DbType.Single; + } + else if (DatabaseClrType == typeof(string)) + { + return DbType.String; + } + else if (DatabaseClrType == typeof(byte[])) + { + return DbType.Binary; + } + else + { + throw new Exception("Can't deduce DbType."); + } + } + } string GetSqlTypeString(string? dbProviderId = null) { @@ -18,13 +70,16 @@ public interface IColumnTypeInfo { DbType.String => "TEXT", DbType.Int16 or DbType.Int32 or DbType.Int64 => "INTEGER", - DbType.Double => "REAL", + DbType.Single or DbType.Double => "REAL", DbType.Binary => "BLOB", _ => throw new Exception($"Unsupported DbType: {DbType}"), }; } - JsonConverter? JsonConverter { get; } + JsonConverter? JsonConverter + { + get { return null; } + } // You must override this method if ClrType != DatabaseClrType object? ConvertFromDatabase(object? databaseValue) @@ -41,8 +96,89 @@ public interface IColumnTypeInfo } } -// TODO: Implement and register this service. public interface IColumnTypeProvider { IColumnTypeInfo Get(Type clrType); } + +public class SimpleColumnTypeInfo<T> : IColumnTypeInfo +{ + public Type ClrType => typeof(T); + public Type DatabaseClrType => typeof(T); +} + +public class DateTimeColumnTypeInfo : IColumnTypeInfo +{ + private DateTimeJsonConverter _jsonConverter = new DateTimeJsonConverter(); + + public Type ClrType => typeof(DateTime); + public Type DatabaseClrType => typeof(string); + + public JsonConverter JsonConverter => _jsonConverter; + + public object? ConvertToDatabase(object? value) + { + if (value is null) return null; + Debug.Assert(value is DateTime); + return ((DateTime)value).ToUniversalTime().ToString("sZ"); + } + + public object? ConvertFromDatabase(object? databaseValue) + { + if (databaseValue is null) return null; + Debug.Assert(databaseValue is string); + return DateTime.ParseExact((string)databaseValue, "sZ", null, DateTimeStyles.AssumeUniversal); + } +} + +public class DateTimeJsonConverter : JsonConverter<DateTime> +{ + public override bool HandleNull => false; + + public override bool CanConvert(Type typeToConvert) + { + return typeToConvert == typeof(DateTime); + } + + public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var s = reader.GetString(); + if (s is null) throw new Exception("Can't convert null to DateTime."); + return DateTime.ParseExact(s, "uZ", null, DateTimeStyles.AssumeUniversal); + } + + public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToUniversalTime().ToString("uZ")); + } +} + +public class ColumnTypeProvider : IColumnTypeProvider +{ + private Dictionary<Type, IColumnTypeInfo> _typeMap = new Dictionary<Type, IColumnTypeInfo>(); + + public ColumnTypeProvider() + { + _typeMap.Add(IColumnTypeInfo.IntColumnTypeInfo.ClrType, IColumnTypeInfo.IntColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.ShortColumnTypeInfo.ClrType, IColumnTypeInfo.ShortColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.SByteColumnTypeInfo.ClrType, IColumnTypeInfo.SByteColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.LongColumnTypeInfo.ClrType, IColumnTypeInfo.LongColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.FloatColumnTypeInfo.ClrType, IColumnTypeInfo.FloatColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.DoubleColumnTypeInfo.ClrType, IColumnTypeInfo.DoubleColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.StringColumnTypeInfo.ClrType, IColumnTypeInfo.StringColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.BytesColumnTypeInfo.ClrType, IColumnTypeInfo.BytesColumnTypeInfo); + _typeMap.Add(IColumnTypeInfo.DateTimeColumnTypeInfo.ClrType, IColumnTypeInfo.DateTimeColumnTypeInfo); + } + + public IColumnTypeInfo Get(Type clrType) + { + if (_typeMap.TryGetValue(clrType, out var typeInfo)) + { + return typeInfo; + } + else + { + throw new Exception($"Unsupported type: {clrType}"); + } + } +} diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs new file mode 100644 index 0000000..92b5660 --- /dev/null +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs @@ -0,0 +1,12 @@ +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace CrupestApi.Commons.Crud; + +public static class CrudServiceCollectionExtensions +{ + public static IServiceCollection UseCrud(this IServiceCollection services) + { + services.TryAddSingleton<IColumnTypeProvider, ColumnTypeProvider>(); + return services; + } +} diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs index 76746b4..5172b34 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs @@ -14,12 +14,10 @@ public static class CrupestApiJsonExtensions config.AllowTrailingCommas = true; config.PropertyNameCaseInsensitive = true; config.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; - foreach (var converter in ColumnTypeRegistry.Instance.GetJsonConverters()) - { - config.Converters.Add(converter); - } }); + // TODO: Register column type provided converters. + return services; } |