aboutsummaryrefslogtreecommitdiff
path: root/docker/crupest-api/CrupestApi/CrupestApi.Commons
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-12-08 21:02:49 +0800
committercrupest <crupest@outlook.com>2022-12-20 20:32:52 +0800
commit20989284d1884892b469e4824e1b8a41d6743bc2 (patch)
treef26880280ee81dabb7bbc876bdb475ed9f77bdeb /docker/crupest-api/CrupestApi/CrupestApi.Commons
parent62c92f97358e2a98271aaf11fdd5626e21cf4689 (diff)
downloadcrupest-20989284d1884892b469e4824e1b8a41d6743bc2.tar.gz
crupest-20989284d1884892b469e4824e1b8a41d6743bc2.tar.bz2
crupest-20989284d1884892b469e4824e1b8a41d6743bc2.zip
Develop secret api. v19
Diffstat (limited to 'docker/crupest-api/CrupestApi/CrupestApi.Commons')
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnTypeInfo.cs146
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs12
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs6
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;
}