diff options
author | crupest <crupest@outlook.com> | 2022-12-11 10:43:56 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-12-20 20:32:53 +0800 |
commit | bd523a6a7cac09fe580223c3d75e41e1e100f603 (patch) | |
tree | 8dcc9fd28c2b7281eb40fa143e96c70518aeefd8 /docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs | |
parent | c53adadcbf93a3b5c1f9c8e2b88bdd0efb122709 (diff) | |
download | crupest-bd523a6a7cac09fe580223c3d75e41e1e100f603.tar.gz crupest-bd523a6a7cac09fe580223c3d75e41e1e100f603.tar.bz2 crupest-bd523a6a7cac09fe580223c3d75e41e1e100f603.zip |
Develop secret api. v26
Diffstat (limited to 'docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs')
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs | 134 |
1 files changed, 74 insertions, 60 deletions
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs index 545397d..800594d 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/ColumnInfo.cs @@ -6,6 +6,9 @@ namespace CrupestApi.Commons.Crud; public class ColumnHooks { + /// <summary> + /// If value is null, then it might because the column does not designated a value or it is designated null. + /// </summary> public delegate void ColumnHookAction(ColumnInfo column, ref object? value); public ColumnHooks(ColumnHookAction afterSelect, ColumnHookAction beforeInsert, ColumnHookAction beforeUpdate) @@ -15,13 +18,13 @@ public class ColumnHooks BeforeUpdate = beforeUpdate; } - // Called after SELECT. + /// <summary>Called after SELECT. Please use multicast if you want to customize it because there are many default behavior in it.</summary public ColumnHookAction AfterSelect; - // Called before INSERT. + /// <summary>Called before INSERT. Please use multicast if you want to customize it because there are many default behavior in it.</summary public ColumnHookAction BeforeInsert; - // Called before UPDATE + /// <summary>Called before UPDATE. Please use multicast if you want to customize it because there are many default behavior in it.</summary public ColumnHookAction BeforeUpdate; } @@ -29,6 +32,9 @@ public class ColumnInfo { private readonly AggregateColumnMetadata _metadata = new AggregateColumnMetadata(); + /// <summary> + /// Initialize a column without corresponding property. + /// </summary> public ColumnInfo(TableInfo table, IColumnMetadata metadata, Type clrType, IColumnTypeProvider typeProvider) { Table = table; @@ -42,6 +48,9 @@ public class ColumnInfo ); } + /// <summary> + /// Initialize a column with corresponding property. + /// </summary> public ColumnInfo(TableInfo table, PropertyInfo propertyInfo, IColumnTypeProvider typeProvider) { Table = table; @@ -62,6 +71,7 @@ public class ColumnInfo } public TableInfo Table { get; } + // If null, there is no corresponding property. public PropertyInfo? PropertyInfo { get; } = null; @@ -71,6 +81,56 @@ public class ColumnInfo public ColumnHooks Hooks { get; } + public bool IsPrimaryKey => Metadata.GetValueOrDefault(ColumnMetadataKeys.IsPrimaryKey) is true; + public bool IsAutoIncrement => Metadata.GetValueOrDefault(ColumnMetadataKeys.IsAutoIncrement) is true; + public bool IsNotNull => IsPrimaryKey || Metadata.GetValueOrDefault(ColumnMetadataKeys.NotNull) is true; + public bool IsClientGenerate => Metadata.GetValueOrDefault(ColumnMetadataKeys.ClientGenerate) is true; + public bool IsNoUpdate => Metadata.GetValueOrDefault(ColumnMetadataKeys.NoUpdate) is true; + /// <summary> + /// This only returns metadata value. It doesn't not fall back to primary column. If you want to get the real key column, go to table info. + /// </summary> + /// <seealso cref="ColumnMetadataKeys.ActAsKey"/> + /// <seealso cref="TableInfo.KeyColumn"/> + public bool IsSpecifiedAsKey => Metadata.GetValueOrDefault(ColumnMetadataKeys.ActAsKey) is true; + public ColumnIndexType Index => Metadata.GetValueOrDefault<ColumnIndexType?>(ColumnMetadataKeys.Index) ?? ColumnIndexType.None; + public UpdateBehavior UpdateBehavior => Metadata.GetValueOrDefault<UpdateBehavior?>(ColumnMetadataKeys.UpdateBehavior) ?? UpdateBehavior.NullIsNotUpdate; + + /// <summary> + /// The real column name. Maybe set in metadata or just the property name. + /// </summary> + /// <value></value> + public string ColumnName + { + get + { + object? value = Metadata.GetValueOrDefault(ColumnMetadataKeys.ColumnName); + Debug.Assert(value is null || value is string); + return ((string?)value ?? PropertyInfo?.Name) ?? throw new Exception("Failed to get column name."); + } + } + + public MethodInfo? DefaultValueGeneratorMethod + { + get + { + object? value = Metadata.GetValueOrDefault(ColumnMetadataKeys.DefaultValueGenerator); + Debug.Assert(value is null || value is string); + MethodInfo? result; + if (value is null) + { + string methodName = ColumnName + "DefaultValueGenerator"; + result = Table.EntityType.GetMethod(methodName, BindingFlags.Static); + } + else + { + string methodName = (string)value; + result = Table.EntityType.GetMethod(methodName, BindingFlags.Static) ?? throw new Exception("The default value generator does not exist."); + } + + return result; + } + } + private void TryCoerceStringFromNullToEmpty(ref object? value) { if (ColumnType.ClrType == typeof(string) && (Metadata.GetValueOrDefault<bool?>(ColumnMetadataKeys.DefaultEmptyForString) ?? false) && value is null) @@ -88,85 +148,39 @@ public class ColumnInfo { if (column.IsClientGenerate && value is not null) { - throw new Exception($"Column {column.ColumnName} can't be set manually."); - } - - var defaultValueGeneratorMethod = DefaultValueGeneratorMethod; - if (defaultValueGeneratorMethod is not null) - { - value = defaultValueGeneratorMethod.Invoke(null, new object[] { }); + throw new UserException($"'{column.ColumnName}' can't be set manually. It is auto generated."); } + DefaultValueGeneratorMethod?.Invoke(null, new object[] { }); OnBeforeSet(column, ref value); } protected void OnBeforeUpdate(ColumnInfo column, ref object? value) { - OnBeforeSet(column, ref value); - if (column.IsNoUpdate) { - throw new Exception($"Column {column.ColumnName} not updatable."); + throw new UserException($"'{column.ColumnName}' is not updatable."); } - } - - protected void OnBeforeSet(ColumnInfo column, ref object? value) - { - TryCoerceStringFromNullToEmpty(ref value); - if (value is null && column.IsNotNull) + if ((column.UpdateBehavior & UpdateBehavior.NullIsSetNull) != 0 && value is null) { - throw new Exception($"Column {column.ColumnName} can't be null."); + value = DbNullValue.Instance; } - } - public string ColumnName - { - get - { - object? value = Metadata.GetValueOrDefault(ColumnMetadataKeys.ColumnName); - Debug.Assert(value is null || value is string); - return ((string?)value ?? PropertyInfo?.Name) ?? throw new Exception("Failed to get column name."); - } + OnBeforeSet(column, ref value); } - public MethodInfo? DefaultValueGeneratorMethod + protected void OnBeforeSet(ColumnInfo column, ref object? value) { - get - { - object? value = Metadata.GetValueOrDefault(ColumnMetadataKeys.DefaultValueGenerator); - Debug.Assert(value is null || value is string); - MethodInfo? result; - if (value is null) - { - string methodName = ColumnName + "DefaultValueGenerator"; - result = Table.EntityType.GetMethod(methodName, BindingFlags.Static); - } - else - { - string methodName = (string)value; - result = Table.EntityType.GetMethod(methodName, BindingFlags.Static) ?? throw new Exception("The default value generator does not exist."); - } + TryCoerceStringFromNullToEmpty(ref value); - return result; + if (value is null && column.IsNotNull) + { + throw new UserException($"{column.ColumnName} can't be null."); } } - public bool IsPrimaryKey => Metadata.GetValueOrDefault(ColumnMetadataKeys.IsPrimaryKey) is true; - public bool IsAutoIncrement => Metadata.GetValueOrDefault(ColumnMetadataKeys.IsAutoIncrement) is true; - public bool IsNotNull => IsPrimaryKey || Metadata.GetValueOrDefault(ColumnMetadataKeys.NotNull) is true; - public bool IsClientGenerate => Metadata.GetValueOrDefault(ColumnMetadataKeys.ClientGenerate) is true; - public bool IsNoUpdate => Metadata.GetValueOrDefault(ColumnMetadataKeys.NoUpdate) is true; - /// <summary> - /// This only returns metadata value. It doesn't not fall back to primary column. If you want to get the real key column, go to table info. - /// </summary> - /// <seealso cref="ColumnMetadataKeys.ActAsKey"/> - /// <seealso cref="TableInfo.KeyColumn"/> - public bool IsSpecifiedAsKey => Metadata.GetValueOrDefault(ColumnMetadataKeys.ActAsKey) is true; - - public ColumnIndexType Index => Metadata.GetValueOrDefault<ColumnIndexType?>(ColumnMetadataKeys.Index) ?? ColumnIndexType.None; - public string GenerateCreateTableColumnString(string? dbProviderId = null) { StringBuilder result = new StringBuilder(); |