|
32 | 32 | import java.security.MessageDigest;
|
33 | 33 | import java.security.NoSuchAlgorithmException;
|
34 | 34 | import java.util.EnumSet;
|
| 35 | +import java.util.HashMap; |
| 36 | +import java.util.List; |
35 | 37 | import java.util.Map;
|
36 | 38 | import java.util.UUID;
|
37 | 39 | import java.util.stream.Collectors;
|
@@ -266,6 +268,25 @@ enum TestEnum {
|
266 | 268 | .noDefault()
|
267 | 269 | .endRecord();
|
268 | 270 |
|
| 271 | + private static final Schema SCHEMA_WITH_MAP; |
| 272 | + |
| 273 | + static { |
| 274 | + SCHEMA_WITH_MAP = |
| 275 | + SchemaBuilder.record("TestMap") |
| 276 | + .fields() |
| 277 | + .name("nested") |
| 278 | + .type() |
| 279 | + .optional() |
| 280 | + .type(BASE_SCHEMA) |
| 281 | + .name("aMap") |
| 282 | + .type() |
| 283 | + .map() |
| 284 | + .values() |
| 285 | + .stringType() |
| 286 | + .mapDefault(ImmutableMap.<String, Object>builder().put("key1", "value1").build()) |
| 287 | + .endRecord(); |
| 288 | + } |
| 289 | + |
269 | 290 | private static GenericRecord baseRecord;
|
270 | 291 | private static GenericRecord logicalTypesRecord;
|
271 | 292 | private static Map<String, Object> baseProtoExpectedFields;
|
@@ -505,4 +526,45 @@ public void testMessageFromGenericRecordLogicalTypes() throws Exception {
|
505 | 526 | assertEquals(7, msg.getAllFields().size());
|
506 | 527 | assertBaseRecord(msg, logicalTypesProtoExpectedFields);
|
507 | 528 | }
|
| 529 | + |
| 530 | + @Test |
| 531 | + public void testMessageFromGenericRecordWithMap() throws Exception { |
| 532 | + // Create a GenericRecord with a map field |
| 533 | + Map<String, String> mapData = new HashMap<>(); |
| 534 | + mapData.put("key1", "value1"); |
| 535 | + mapData.put("key2", "value2"); |
| 536 | + GenericRecord recordWithMap = |
| 537 | + new GenericRecordBuilder(SCHEMA_WITH_MAP) |
| 538 | + .set("nested", baseRecord) |
| 539 | + .set("aMap", mapData) |
| 540 | + .build(); |
| 541 | + |
| 542 | + Descriptors.Descriptor descriptor = |
| 543 | + TableRowToStorageApiProto.getDescriptorFromTableSchema( |
| 544 | + AvroGenericRecordToStorageApiProto.protoTableSchemaFromAvroSchema(SCHEMA_WITH_MAP), |
| 545 | + true, |
| 546 | + false); |
| 547 | + DynamicMessage msg = |
| 548 | + AvroGenericRecordToStorageApiProto.messageFromGenericRecord( |
| 549 | + descriptor, recordWithMap, null, -1); |
| 550 | + |
| 551 | + assertEquals(2, msg.getAllFields().size()); |
| 552 | + |
| 553 | + Map<String, Descriptors.FieldDescriptor> fieldDescriptors = |
| 554 | + descriptor.getFields().stream() |
| 555 | + .collect(Collectors.toMap(Descriptors.FieldDescriptor::getName, Functions.identity())); |
| 556 | + DynamicMessage nestedMsg = (DynamicMessage) msg.getField(fieldDescriptors.get("nested")); |
| 557 | + assertBaseRecord(nestedMsg, baseProtoExpectedFields); |
| 558 | + |
| 559 | + // Assert the map field |
| 560 | + List<DynamicMessage> list = (List<DynamicMessage>) msg.getField(fieldDescriptors.get("amap")); |
| 561 | + // Convert the list of DynamicMessages back to a map |
| 562 | + Map<String, String> actualMap = new HashMap<>(); |
| 563 | + for (DynamicMessage entry : list) { |
| 564 | + String key = (String) entry.getField(entry.getDescriptorForType().findFieldByName("key")); |
| 565 | + String value = (String) entry.getField(entry.getDescriptorForType().findFieldByName("value")); |
| 566 | + actualMap.put(key, value); |
| 567 | + } |
| 568 | + assertEquals(mapData, actualMap); |
| 569 | + } |
508 | 570 | }
|
0 commit comments