Skip to content

Commit 8ad23ab

Browse files
authored
Merge pull request #106 from mrt181/docs/as-struct
test: tests and docs for nested arrays that should be marked as structs
2 parents 496f361 + 579b116 commit 8ad23ab

File tree

2 files changed

+124
-1
lines changed

2 files changed

+124
-1
lines changed

Tests/ksqlDB.RestApi.Client.Tests/KSql/RestApi/Generators/StatementGeneratorTests.cs

+91
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,97 @@ public void CreateTable_UseModelBuilder_WithFieldAsStruct()
193193
Headers ARRAY<STRUCT<Key VARCHAR, Value BYTES>>
194194
) WITH ( KAFKA_TOPIC='my_topic', VALUE_FORMAT='Json', PARTITIONS='3' );".ReplaceLineEndings());
195195
}
196+
197+
private record Child : Record
198+
{
199+
public First[] Firsts { get; init; } = null!;
200+
}
201+
202+
private record First
203+
{
204+
public Second[] Seconds { get; init; } = null!;
205+
}
206+
207+
private record Second
208+
{
209+
public string Test { get; init; } = null!;
210+
}
211+
212+
[Test]
213+
public void CreateTable_UseModelBuilder_WithNestedArrayFieldAsStruct()
214+
{
215+
//Arrange
216+
var modelBuilder = new ModelBuilder();
217+
modelBuilder.Entity<Child>().Property(b => b.Headers).AsStruct();
218+
modelBuilder.Entity<Child>().Property(b => b.Firsts).AsStruct();
219+
modelBuilder.Entity<Child>().Property(b => b.Firsts.FirstOrDefault()!.Seconds).AsStruct();
220+
221+
var creationMetadata = new EntityCreationMetadata("my_topic", partitions: 3);
222+
223+
//Act
224+
var statement = new StatementGenerator(modelBuilder).CreateTable<Child>(
225+
creationMetadata,
226+
ifNotExists: true
227+
);
228+
229+
//Assert
230+
statement
231+
.Should()
232+
.Be(
233+
@"CREATE TABLE IF NOT EXISTS Children (
234+
Firsts ARRAY<STRUCT<Seconds ARRAY<STRUCT<Test VARCHAR>>>>,
235+
Headers ARRAY<STRUCT<Key VARCHAR, Value BYTES>>
236+
) WITH ( KAFKA_TOPIC='my_topic', VALUE_FORMAT='Json', PARTITIONS='3' );".ReplaceLineEndings()
237+
);
238+
}
239+
240+
private class Child2
241+
{
242+
public First2[] Firsts { get; set; }
243+
}
244+
245+
private class First2
246+
{
247+
public Second2[] Seconds { get; set; }
248+
}
249+
250+
private class Second2
251+
{
252+
public Third[] Thirds { get; set; }
253+
}
254+
255+
private class Third
256+
{
257+
public string Test1 { get; set; }
258+
public string Test2 { get; set; }
259+
}
260+
261+
[Test]
262+
public void CreateTable_UseModelBuilder_WithNestedArrayFieldAsStruct_2()
263+
{
264+
//Arrange
265+
var modelBuilder = new ModelBuilder();
266+
modelBuilder.Entity<Child2>().Property(b => b.Firsts).AsStruct();
267+
modelBuilder.Entity<Child2>().Property(b => b.Firsts.FirstOrDefault()!.Seconds).AsStruct();
268+
modelBuilder.Entity<Child2>().Property(b => b.Firsts.FirstOrDefault()!.Seconds.FirstOrDefault()!.Thirds).AsStruct();
269+
270+
var creationMetadata = new EntityCreationMetadata("my_topic", partitions: 3);
271+
272+
//Act
273+
var statement = new StatementGenerator(modelBuilder).CreateTable<Child2>(
274+
creationMetadata,
275+
ifNotExists: true
276+
);
277+
278+
//Assert
279+
statement
280+
.Should()
281+
.Be(
282+
@"CREATE TABLE IF NOT EXISTS Child2s (
283+
Firsts ARRAY<STRUCT<Seconds ARRAY<STRUCT<Thirds ARRAY<STRUCT<Test1 VARCHAR, Test2 VARCHAR>>>>>>
284+
) WITH ( KAFKA_TOPIC='my_topic', VALUE_FORMAT='Json', PARTITIONS='3' );".ReplaceLineEndings()
285+
);
286+
}
196287
}
197288

198289
internal class Port

docs/modelbuilder.md

+33-1
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,38 @@ CREATE TABLE IF NOT EXISTS Records (
318318
) WITH ( KAFKA_TOPIC='my_topic', VALUE_FORMAT='Json', PARTITIONS='3' );
319319
```
320320

321+
For array fields that contain a type that is a struct and that again contains a type that is a struct, it's necessary to mark the inner type as a struct type as well:
322+
```C#
323+
324+
private record Child : Record
325+
{
326+
public First[] Firsts { get; init; } = null!;
327+
}
328+
329+
private record First
330+
{
331+
public Second[] Seconds { get; init; } = null!;
332+
}
333+
334+
private record Second
335+
{
336+
public string Test { get; init; } = null!;
337+
}
338+
```
339+
```C#
340+
ModelBuilder builder = new();
341+
342+
builder.Entity<Child>()
343+
.Property(b => b.Headers)
344+
.AsStruct();
345+
builder.Entity<Child>()
346+
.Property(b => b.Firsts)
347+
.AsStruct();
348+
builder.Entity<Child>()
349+
.Property(b => b.Firsts.FirstOrDefault()!.Seconds)
350+
.AsStruct();
351+
```
352+
321353
### IgnoreInDML
322354
**v6.4.0**
323355

@@ -417,4 +449,4 @@ Valid pseudocolumn names are:
417449
- Headers
418450
- RowOffset
419451
- RowPartition
420-
- RowTime
452+
- RowTime

0 commit comments

Comments
 (0)