Skip to content

Commit cc3243b

Browse files
committed
[ksqlDb.RestApi.Client]: added IgnoreInDML function to the fluent API, introduced IgnoreAttribute, and fixed the issue where IgnoreByInsertsAttribute incorrectly excluded properties from DDL statements #90
1 parent 821edbe commit cc3243b

File tree

8 files changed

+70
-29
lines changed

8 files changed

+70
-29
lines changed

ksqlDb.RestApi.Client/FluentAPI/Builders/FieldTypeBuilder.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Linq.Expressions;
12
using ksqlDb.RestApi.Client.Metadata;
23

34
namespace ksqlDb.RestApi.Client.FluentAPI.Builders
@@ -9,11 +10,17 @@ namespace ksqlDb.RestApi.Client.FluentAPI.Builders
910
public interface IFieldTypeBuilder<TProperty>
1011
{
1112
/// <summary>
12-
/// Marks the field as ignored, excluding it from the entity's schema.
13+
/// Marks the field as ignored, excluding it from the entity's schema, preventing it from being included in both DDL and DML statements.
1314
/// </summary>
1415
/// <returns>The field type builder for chaining additional configuration.</returns>
1516
public IFieldTypeBuilder<TProperty> Ignore();
1617

18+
/// <summary>
19+
/// Marks the field to be excluded from data manipulation operations, preventing it from being included in DML statements such as INSERT.
20+
/// </summary>
21+
/// <returns>The field type builder for chaining additional configuration.</returns>
22+
public IFieldTypeBuilder<TProperty> IgnoreInDML();
23+
1724
/// <summary>
1825
/// Marks the field as HEADERS.
1926
/// </summary>
@@ -55,9 +62,16 @@ public IFieldTypeBuilder<TProperty> Ignore()
5562
return this;
5663
}
5764

65+
public IFieldTypeBuilder<TProperty> IgnoreInDML()
66+
{
67+
fieldMetadata.IgnoreInDML = true;
68+
return this;
69+
}
70+
5871
public IFieldTypeBuilder<TProperty> WithHeaders()
5972
{
6073
fieldMetadata.HasHeaders = true;
74+
IgnoreInDML();
6175
return this;
6276
}
6377
}

ksqlDb.RestApi.Client/KSql/RestApi/Extensions/MemberInfoExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ internal static class MemberInfoExtensions
1212
/// </summary>
1313
/// <param name="memberInfo"></param>
1414
/// <param name="escaping"></param>
15-
/// <param name="modelBuilder"></param>
15+
/// <param name="metadataProvider"></param>
1616
/// <returns>the <c>memberInfo.Name</c> modified based on the provided <c>format</c></returns>
17-
public static string Format(this MemberInfo memberInfo, IdentifierEscaping escaping, ModelBuilder modelBuilder) => IdentifierUtil.Format(memberInfo, escaping, modelBuilder);
17+
public static string Format(this MemberInfo memberInfo, IdentifierEscaping escaping, IMetadataProvider metadataProvider) => IdentifierUtil.Format(memberInfo, escaping, metadataProvider);
1818
}
1919
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace ksqlDB.RestApi.Client.KSql.RestApi.Statements.Annotations
2+
{
3+
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
4+
public sealed class IgnoreAttribute : Attribute
5+
{
6+
}
7+
}

ksqlDb.RestApi.Client/KSql/RestApi/Statements/CreateInsert.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@
55
using ksqlDB.RestApi.Client.KSql.RestApi.Statements.Inserts;
66
using ksqlDB.RestApi.Client.KSql.RestApi.Statements.Properties;
77
using ksqlDb.RestApi.Client.FluentAPI.Builders;
8+
using ksqlDB.RestApi.Client.KSql.RestApi.Statements.Annotations;
9+
using ksqlDb.RestApi.Client.Metadata;
810

911
namespace ksqlDB.RestApi.Client.KSql.RestApi.Statements;
1012

1113
internal sealed class CreateInsert : EntityInfo
1214
{
13-
private readonly ModelBuilder modelBuilder;
15+
private readonly IMetadataProvider metadataProvider;
1416

15-
public CreateInsert(ModelBuilder modelBuilder)
16-
: base(modelBuilder)
17+
public CreateInsert(ModelBuilder metadataProvider)
18+
: base(metadataProvider)
1719
{
18-
this.modelBuilder = modelBuilder;
20+
this.metadataProvider = metadataProvider;
1921
}
2022

2123
internal string Generate<T>(T entity, InsertProperties insertProperties)
@@ -50,11 +52,11 @@ internal string Generate<T>(InsertValues<T> insertValues, InsertProperties inser
5052
valuesStringBuilder.Append(", ");
5153
}
5254

53-
columnsStringBuilder.Append(memberInfo.Format(insertProperties.IdentifierEscaping, modelBuilder));
55+
columnsStringBuilder.Append(memberInfo.Format(insertProperties.IdentifierEscaping, metadataProvider));
5456

5557
var type = GetMemberType(memberInfo);
5658

57-
var value = GetValue(insertValues, insertProperties, memberInfo, type, mi => IdentifierUtil.Format(mi, insertProperties.IdentifierEscaping, modelBuilder));
59+
var value = GetValue(insertValues, insertProperties, memberInfo, type, mi => IdentifierUtil.Format(mi, insertProperties.IdentifierEscaping, metadataProvider));
5860

5961
valuesStringBuilder.Append(value);
6062
}
@@ -68,15 +70,24 @@ internal string Generate<T>(InsertValues<T> insertValues, InsertProperties inser
6870
private object GetValue<T>(InsertValues<T> insertValues, InsertProperties insertProperties,
6971
MemberInfo memberInfo, Type type, Func<MemberInfo, string> formatter)
7072
{
71-
var hasValue = insertValues.PropertyValues.ContainsKey(memberInfo.Format(insertProperties.IdentifierEscaping, modelBuilder));
73+
var hasValue = insertValues.PropertyValues.ContainsKey(memberInfo.Format(insertProperties.IdentifierEscaping, metadataProvider));
7274

7375
object value;
7476

7577
if (hasValue)
76-
value = insertValues.PropertyValues[memberInfo.Format(insertProperties.IdentifierEscaping, modelBuilder)];
78+
value = insertValues.PropertyValues[memberInfo.Format(insertProperties.IdentifierEscaping, metadataProvider)];
7779
else
78-
value = new CreateKSqlValue(modelBuilder).ExtractValue(insertValues.Entity, insertProperties, memberInfo, type, formatter);
80+
value = new CreateKSqlValue(metadataProvider).ExtractValue(insertValues.Entity, insertProperties, memberInfo, type, formatter);
7981

8082
return value;
8183
}
84+
85+
protected override bool IncludeMemberInfo(EntityMetadata? entityMetadata, MemberInfo memberInfo)
86+
{
87+
var fieldMetadata = entityMetadata?.GetFieldMetadataBy(memberInfo);
88+
if (fieldMetadata is {IgnoreInDML: true})
89+
return false;
90+
91+
return base.IncludeMemberInfo(entityMetadata, memberInfo) && !memberInfo.GetCustomAttributes().OfType<IgnoreByInsertsAttribute>().Any();
92+
}
8293
}

ksqlDb.RestApi.Client/KSql/RestApi/Statements/EntityInfo.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using ksqlDb.RestApi.Client.FluentAPI.Builders;
33
using ksqlDB.RestApi.Client.KSql.RestApi.Statements.Annotations;
44
using ksqlDb.RestApi.Client.KSql.RestApi.Statements.Providers;
5+
using ksqlDb.RestApi.Client.Metadata;
56

67
namespace ksqlDB.RestApi.Client.KSql.RestApi.Statements;
78

@@ -21,18 +22,19 @@ protected IEnumerable<MemberInfo> Members(Type type, bool? includeReadOnly = nul
2122
var properties = type
2223
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
2324
.Where(c => c.CanWrite || (includeReadOnly.HasValue && includeReadOnly.Value))
24-
.OfType<MemberInfo>()
25-
.Concat(fields);
25+
.OfType<MemberInfo>();
26+
27+
var members = properties.Concat(fields);
2628

2729
var entityMetadata = metadataProvider.GetEntities().FirstOrDefault(c => c.Type == type);
28-
29-
return properties.Where(c =>
30-
{
31-
var fieldMetadata = entityMetadata?.GetFieldMetadataBy(c);
32-
if (fieldMetadata is {Ignore: true}) return false;
3330

34-
return !c.GetCustomAttributes().OfType<IgnoreByInsertsAttribute>().Any();
35-
});
31+
return members.Where(memberInfo => IncludeMemberInfo(entityMetadata, memberInfo));
32+
}
33+
34+
protected virtual bool IncludeMemberInfo(EntityMetadata? entityMetadata, MemberInfo memberInfo)
35+
{
36+
var fieldMetadata = entityMetadata?.GetFieldMetadataBy(memberInfo);
37+
return fieldMetadata is not {Ignore: true} && !memberInfo.GetCustomAttributes().OfType<IgnoreAttribute>().Any();
3638
}
3739

3840
protected static Type GetMemberType(MemberInfo memberInfo)

ksqlDb.RestApi.Client/Metadata/BytesArrayFieldMetadata.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ namespace ksqlDb.RestApi.Client.Metadata
33
internal sealed record BytesArrayFieldMetadata : FieldMetadata
44
{
55
public BytesArrayFieldMetadata(FieldMetadata fieldMetadata)
6+
: base(fieldMetadata)
67
{
7-
MemberInfo = fieldMetadata.MemberInfo;
8-
Ignore = fieldMetadata.Ignore;
9-
Path = fieldMetadata.Path;
10-
FullPath = fieldMetadata.FullPath;
118
}
129

1310
public string? Header { get; internal set; }

ksqlDb.RestApi.Client/Metadata/DecimalFieldMetadata.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ namespace ksqlDb.RestApi.Client.Metadata
33
internal sealed record DecimalFieldMetadata : FieldMetadata
44
{
55
public DecimalFieldMetadata(FieldMetadata fieldMetadata)
6+
: base(fieldMetadata)
67
{
7-
MemberInfo = fieldMetadata.MemberInfo;
8-
Ignore = fieldMetadata.Ignore;
9-
Path = fieldMetadata.Path;
10-
FullPath = fieldMetadata.FullPath;
118
}
129

1310
public short Precision { get; internal set; }

ksqlDb.RestApi.Client/Metadata/FieldMetadata.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,21 @@ namespace ksqlDb.RestApi.Client.Metadata
44
{
55
internal record FieldMetadata
66
{
7+
public FieldMetadata(FieldMetadata fieldMetadata)
8+
{
9+
MemberInfo = fieldMetadata.MemberInfo;
10+
Ignore = fieldMetadata.Ignore;
11+
IgnoreInDML = fieldMetadata.IgnoreInDML;
12+
HasHeaders = fieldMetadata.HasHeaders;
13+
IsStruct = fieldMetadata.IsStruct;
14+
Path = fieldMetadata.Path;
15+
FullPath = fieldMetadata.FullPath;
16+
ColumnName = fieldMetadata.ColumnName;
17+
}
18+
719
internal MemberInfo MemberInfo { get; init; } = null!;
820
public bool Ignore { get; internal set; }
21+
public bool IgnoreInDML { get; internal set; }
922
public bool HasHeaders { get; internal set; }
1023
internal bool IsStruct { get; set; }
1124
internal string Path { get; init; } = null!;

0 commit comments

Comments
 (0)