Skip to content

Commit 14d8cbd

Browse files
committed
[ksqlDb.RestApi.Client]: added AsStruct to Fluent API
1 parent be0ee7d commit 14d8cbd

File tree

5 files changed

+42
-14
lines changed

5 files changed

+42
-14
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ public interface IFieldTypeBuilder<TProperty>
2626
/// <param name="columnName">The name of the column in the record schema.</param>
2727
/// <returns>The same <see cref="IFieldTypeBuilder{TProperty}"/> instance so that multiple calls can be chained.</returns>
2828
IFieldTypeBuilder<TProperty> HasColumnName(string columnName);
29+
30+
/// <summary>
31+
/// Marks the field as a ksqldb STRUCT type.
32+
/// </summary>
33+
/// <returns>The field type builder for chaining additional configuration.</returns>
34+
IFieldTypeBuilder<TProperty> AsStruct();
2935
}
3036

3137
internal class FieldTypeBuilder<TProperty>(FieldMetadata fieldMetadata)
@@ -37,6 +43,12 @@ public IFieldTypeBuilder<TProperty> HasColumnName(string columnName)
3743
return this;
3844
}
3945

46+
public IFieldTypeBuilder<TProperty> AsStruct()
47+
{
48+
fieldMetadata.IsStruct = true;
49+
return this;
50+
}
51+
4052
public IFieldTypeBuilder<TProperty> Ignore()
4153
{
4254
fieldMetadata.Ignore = true;

ksqlDb.RestApi.Client/KSql/RestApi/Generators/TypeGenerator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ namespace ksqlDB.RestApi.Client.KSql.RestApi.Generators;
1111

1212
internal sealed class TypeGenerator(IMetadataProvider metadataProvider) : EntityInfo(metadataProvider)
1313
{
14-
private readonly KSqlTypeTranslator typeTranslator = new(metadataProvider);
15-
1614
internal string Print<T>(TypeProperties properties)
1715
{
1816
StringBuilder stringBuilder = new();
@@ -30,11 +28,13 @@ private void PrintProperties<T>(StringBuilder stringBuilder, IdentifierEscaping
3028
{
3129
var ksqlProperties = new List<string>();
3230

31+
KSqlTypeTranslator<T> typeTranslator = new(metadataProvider);
32+
3333
foreach (var memberInfo in Members<T>())
3434
{
3535
var type = GetMemberType(memberInfo);
3636

37-
var ksqlType = typeTranslator.Translate(type, escaping);
37+
var ksqlType = typeTranslator.Translate(type, memberInfo, escaping);
3838

3939
var memberName = memberInfo.GetMemberName(metadataProvider);
4040
var columnDefinition = $"{EscapeName(memberName, escaping)} {ksqlType}{typeTranslator.ExploreAttributes(typeof(T), memberInfo, type)}";

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ internal sealed class CreateEntity(IMetadataProvider metadataProvider) : EntityI
1313
{
1414
private readonly StringBuilder stringBuilder = new();
1515

16-
private readonly KSqlTypeTranslator typeTranslator = new(metadataProvider);
17-
1816
internal string Print<T>(StatementContext statementContext, EntityCreationMetadata metadata, bool? ifNotExists)
1917
{
2018
stringBuilder.Clear();
@@ -42,12 +40,13 @@ internal string Print<T>(StatementContext statementContext, EntityCreationMetada
4240
private void PrintProperties<T>(StatementContext statementContext, EntityCreationMetadata metadata)
4341
{
4442
var ksqlProperties = new List<string>();
43+
KSqlTypeTranslator<T> typeTranslator = new(metadataProvider);
4544

4645
foreach (var memberInfo in Members<T>(metadata.IncludeReadOnlyProperties))
4746
{
4847
var type = GetMemberType(memberInfo);
4948

50-
var ksqlType = typeTranslator.Translate(type, metadata.IdentifierEscaping);
49+
var ksqlType = typeTranslator.Translate(type, memberInfo, metadata.IdentifierEscaping);
5150

5251
var columnName = IdentifierUtil.Format(memberInfo, metadata.IdentifierEscaping, metadataProvider);
5352
string columnDefinition = $"\t{columnName} {ksqlType}{typeTranslator.ExploreAttributes(typeof(T), memberInfo, type)}";

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99

1010
namespace ksqlDB.RestApi.Client.KSql.RestApi.Statements
1111
{
12-
internal sealed class KSqlTypeTranslator(IMetadataProvider metadataProvider) : EntityInfo(metadataProvider)
12+
internal sealed class KSqlTypeTranslator<TEntity>(IMetadataProvider metadataProvider) : EntityInfo(metadataProvider)
1313
{
1414
private readonly IMetadataProvider metadataProvider = metadataProvider;
1515
private readonly DecimalTypeTranslator decimalTypeTranslator = new(metadataProvider);
1616

17-
internal string Translate(Type type, IdentifierEscaping escaping = IdentifierEscaping.Never)
17+
internal string Translate(Type type, MemberInfo? memberInfo = null, IdentifierEscaping escaping = IdentifierEscaping.Never)
1818
{
1919
var ksqlType = string.Empty;
2020

@@ -25,16 +25,16 @@ internal string Translate(Type type, IdentifierEscaping escaping = IdentifierEsc
2525
var elementType = type.GetElementType();
2626
if (elementType == null)
2727
throw new InvalidOperationException(nameof(elementType));
28-
var elementTypeName = Translate(elementType, escaping);
28+
var elementTypeName = Translate(elementType, memberInfo, escaping);
2929

3030
ksqlType = $"{KSqlTypes.Array}<{elementTypeName}>";
3131
}
3232
else if (type.IsDictionary())
3333
{
3434
Type[] typeParameters = type.GetGenericArguments();
3535

36-
var keyType = Translate(typeParameters[0], escaping);
37-
var valueType = Translate(typeParameters[1], escaping);
36+
var keyType = Translate(typeParameters[0], memberInfo, escaping);
37+
var valueType = Translate(typeParameters[1], memberInfo, escaping);
3838

3939
ksqlType = $"{KSqlTypes.Map}<{keyType}, {valueType}>";
4040
}
@@ -58,7 +58,7 @@ internal string Translate(Type type, IdentifierEscaping escaping = IdentifierEsc
5858
ksqlType = KSqlTypes.Time;
5959
else if (type == typeof(DateTimeOffset))
6060
ksqlType = KSqlTypes.Timestamp;
61-
else if (!type.IsGenericType && type.TryGetAttribute<StructAttribute>() != null)
61+
else if (!type.IsGenericType && IsStructType(type, memberInfo))
6262
{
6363
var ksqlProperties = GetProperties(type, escaping);
6464

@@ -88,7 +88,7 @@ internal string Translate(Type type, IdentifierEscaping escaping = IdentifierEsc
8888

8989
if (elementType != null)
9090
{
91-
string ksqlElementType = Translate(elementType, escaping);
91+
string ksqlElementType = Translate(elementType, memberInfo, escaping);
9292

9393
ksqlType = $"{KSqlTypes.Array}<{ksqlElementType}>";
9494
}
@@ -97,6 +97,22 @@ internal string Translate(Type type, IdentifierEscaping escaping = IdentifierEsc
9797
return ksqlType;
9898
}
9999

100+
private bool IsStructType(Type type, MemberInfo? memberInfo)
101+
{
102+
if (type.TryGetAttribute<StructAttribute>() != null)
103+
return true;
104+
105+
if (memberInfo == null)
106+
return false;
107+
108+
var entityMetadata = metadataProvider.GetEntities().FirstOrDefault(c => c.Type == typeof(TEntity));
109+
var fieldMetadata = entityMetadata?.GetFieldMetadataBy(memberInfo);
110+
return fieldMetadata is
111+
{
112+
IsStruct: true
113+
};
114+
}
115+
100116
internal IEnumerable<string> GetProperties(Type type, IdentifierEscaping escaping)
101117
{
102118
var ksqlProperties = new List<string>();
@@ -105,7 +121,7 @@ internal IEnumerable<string> GetProperties(Type type, IdentifierEscaping escapin
105121
{
106122
var memberType = GetMemberType(memberInfo);
107123

108-
var ksqlType = Translate(memberType, escaping);
124+
var ksqlType = Translate(memberType, memberInfo, escaping);
109125

110126
string columnDefinition = $"{memberInfo.Format(escaping, metadataProvider as ModelBuilder)} {ksqlType}{ExploreAttributes(type, memberInfo, memberType)}";
111127

ksqlDb.RestApi.Client/Metadata/FieldMetadata.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ internal record FieldMetadata
77
internal MemberInfo MemberInfo { get; init; } = null!;
88
public bool Ignore { get; internal set; }
99
public bool HasHeaders { get; internal set; }
10+
internal bool IsStruct { get; set; }
1011
internal string Path { get; init; } = null!;
1112
internal string FullPath { get; init; } = null!;
1213
public string? ColumnName { get; set; }

0 commit comments

Comments
 (0)