Skip to content

Commit 71a4876

Browse files
committed
Addressed PR feedback
1 parent 32a86af commit 71a4876

6 files changed

Lines changed: 1183 additions & 376 deletions

File tree

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/extensions/AutoGeneratedTimestampRecordExtension.java

Lines changed: 305 additions & 162 deletions
Large diffs are not rendered by default.

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/EnhancedClientUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public static boolean hasMap(AttributeValue attributeValue) {
221221
* @param attributeName the attribute name; must not be null or empty
222222
* @return the nested schema, or empty if unavailable
223223
*/
224-
public static Optional<? extends TableSchema<?>> getNestedSchema(TableSchema<?> parentSchema, CharSequence attributeName) {
224+
public static Optional<TableSchema<?>> getNestedSchema(TableSchema<?> parentSchema, String attributeName) {
225225
if (parentSchema == null) {
226226
throw new IllegalArgumentException("Parent schema cannot be null.");
227227
}
@@ -244,6 +244,6 @@ public static Optional<? extends TableSchema<?>> getNestedSchema(TableSchema<?>
244244
enhancedType = rawClassParameters.get(0);
245245
}
246246

247-
return enhancedType.tableSchema();
247+
return enhancedType.tableSchema().flatMap(Optional::of);
248248
}
249249
}

services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/extensions/utility/NestedRecordUtils.java

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.HashMap;
2222
import java.util.List;
2323
import java.util.Map;
24+
import java.util.Objects;
2425
import java.util.Optional;
2526
import java.util.regex.Pattern;
2627
import software.amazon.awssdk.annotations.SdkInternalApi;
@@ -65,45 +66,47 @@ public static TableSchema<?> getTableSchemaForListElement(TableSchema<?> rootSch
6566
public static TableSchema<?> getTableSchemaForListElement(
6667
TableSchema<?> rootSchema,
6768
String key,
68-
Map<SchemaLookupKey, Optional<? extends TableSchema<?>>> nestedSchemaCache) {
69-
TableSchema<?> listElementSchema;
70-
71-
if (!key.contains(NESTED_OBJECT_UPDATE)) {
72-
Optional<? extends TableSchema<?>> staticSchema = getNestedSchemaCached(nestedSchemaCache, rootSchema, key);
73-
if (staticSchema.isPresent()) {
74-
listElementSchema = staticSchema.get();
75-
} else {
76-
AttributeConverter<?> converter = rootSchema.converterForAttribute(key);
77-
if (converter == null) {
78-
throw new IllegalArgumentException("No converter found for attribute: " + key);
79-
}
80-
List<EnhancedType<?>> rawClassParameters = converter.type().rawClassParameters();
81-
if (CollectionUtils.isNullOrEmpty(rawClassParameters)) {
82-
throw new IllegalArgumentException("No type parameters found for list attribute: " + key);
83-
}
84-
listElementSchema = TableSchema.fromClass(rawClassParameters.get(0).rawClass());
85-
}
86-
} else {
87-
String[] parts = NESTED_OBJECT_PATTERN.split(key);
88-
TableSchema<?> currentSchema = rootSchema;
69+
Map<SchemaLookupKey, Optional<TableSchema<?>>> nestedSchemaCache) {
8970

90-
for (int i = 0; i < parts.length - 1; i++) {
91-
Optional<? extends TableSchema<?>> nestedSchema =
92-
getNestedSchemaCached(nestedSchemaCache, currentSchema, parts[i]);
93-
if (nestedSchema.isPresent()) {
94-
currentSchema = nestedSchema.get();
95-
}
96-
}
71+
if (key.contains(NESTED_OBJECT_UPDATE)) {
72+
return listElementSchemaForDelimitedKey(rootSchema, key, nestedSchemaCache);
73+
}
9774

98-
String attributeName = parts[parts.length - 1];
99-
Optional<? extends TableSchema<?>> nestedListSchema =
100-
getNestedSchemaCached(nestedSchemaCache, currentSchema, attributeName);
75+
Optional<TableSchema<?>> staticSchema = getNestedSchemaCached(nestedSchemaCache, rootSchema, key);
76+
if (staticSchema.isPresent()) {
77+
return staticSchema.get();
78+
}
10179

102-
listElementSchema = nestedListSchema.orElseThrow(
103-
() -> new IllegalArgumentException("Unable to resolve schema for list element at: " + key));
80+
AttributeConverter<?> converter = rootSchema.converterForAttribute(key);
81+
if (converter == null) {
82+
throw new IllegalArgumentException("No converter found for attribute: " + key);
83+
}
84+
List<EnhancedType<?>> rawClassParameters = converter.type().rawClassParameters();
85+
if (CollectionUtils.isNullOrEmpty(rawClassParameters)) {
86+
throw new IllegalArgumentException("No type parameters found for list attribute: " + key);
10487
}
88+
return TableSchema.fromClass(rawClassParameters.get(0).rawClass());
89+
}
90+
91+
private static TableSchema<?> listElementSchemaForDelimitedKey(
92+
TableSchema<?> rootSchema,
93+
String key,
94+
Map<SchemaLookupKey, Optional<TableSchema<?>>> nestedSchemaCache) {
95+
96+
String[] parts = NESTED_OBJECT_PATTERN.split(key);
97+
TableSchema<?> currentSchema = rootSchema;
10598

106-
return listElementSchema;
99+
for (int i = 0; i < parts.length - 1; i++) {
100+
Optional<TableSchema<?>> nestedSchema =
101+
getNestedSchemaCached(nestedSchemaCache, currentSchema, parts[i]);
102+
if (nestedSchema.isPresent()) {
103+
currentSchema = nestedSchema.get();
104+
}
105+
}
106+
107+
String attributeName = parts[parts.length - 1];
108+
return getNestedSchemaCached(nestedSchemaCache, currentSchema, attributeName)
109+
.orElseThrow(() -> new IllegalArgumentException("Unable to resolve schema for list element at: " + key));
107110
}
108111

109112
/**
@@ -134,7 +137,7 @@ public static Map<String, TableSchema<?>> resolveSchemasPerPath(Map<String, Attr
134137
public static Map<String, TableSchema<?>> resolveSchemasPerPath(
135138
Map<String, AttributeValue> attributesToSet,
136139
TableSchema<?> rootSchema,
137-
Map<SchemaLookupKey, Optional<? extends TableSchema<?>>> nestedSchemaCache) {
140+
Map<SchemaLookupKey, Optional<TableSchema<?>>> nestedSchemaCache) {
138141

139142
Map<String, TableSchema<?>> schemaMap = new HashMap<>();
140143
schemaMap.put("", rootSchema);
@@ -154,7 +157,7 @@ public static Map<String, TableSchema<?>> resolveSchemasPerPath(
154157
String path = pathBuilder.toString();
155158

156159
if (!schemaMap.containsKey(path)) {
157-
Optional<? extends TableSchema<?>> nestedSchema =
160+
Optional<TableSchema<?>> nestedSchema =
158161
getNestedSchemaCached(nestedSchemaCache, currentSchema, parts[i]);
159162

160163
if (nestedSchema.isPresent()) {
@@ -197,8 +200,8 @@ public static String reconstructCompositeKey(String path, String attributeName)
197200
* Cached wrapper around {@link software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils#getNestedSchema}. Cache
198201
* key is based on (parent schema identity, attribute name).
199202
*/
200-
public static Optional<? extends TableSchema<?>> getNestedSchemaCached(
201-
Map<SchemaLookupKey, Optional<? extends TableSchema<?>>> cache,
203+
public static Optional<TableSchema<?>> getNestedSchemaCached(
204+
Map<SchemaLookupKey, Optional<TableSchema<?>>> cache,
202205
TableSchema<?> parentSchema,
203206
String attributeName) {
204207

@@ -215,15 +218,16 @@ public static Optional<? extends TableSchema<?>> getNestedSchemaCached(
215218
public static TableSchema<?> getListElementSchemaCached(
216219
Map<SchemaLookupKey, TableSchema<?>> cache,
217220
TableSchema<?> parentSchema,
218-
String attributeName) {
221+
String attributeName,
222+
Map<SchemaLookupKey, Optional<TableSchema<?>>> nestedSchemaCache) {
219223

220224
SchemaLookupKey key = new SchemaLookupKey(parentSchema, attributeName);
221225

222226
if (cache.containsKey(key)) {
223227
return cache.get(key);
224228
}
225229

226-
TableSchema<?> schema = getTableSchemaForListElement(parentSchema, attributeName, new HashMap<>());
230+
TableSchema<?> schema = getTableSchemaForListElement(parentSchema, attributeName, nestedSchemaCache);
227231
cache.put(key, schema);
228232
return schema;
229233
}
@@ -235,29 +239,24 @@ public static TableSchema<?> getListElementSchemaCached(
235239
public static final class SchemaLookupKey {
236240
private final TableSchema<?> parentSchema;
237241
private final String attributeName;
238-
private final int hash;
239242

240243
public SchemaLookupKey(TableSchema<?> parentSchema, String attributeName) {
241244
this.parentSchema = parentSchema;
242245
this.attributeName = attributeName;
243-
this.hash = 31 * System.identityHashCode(parentSchema) + attributeName.hashCode();
244246
}
245247

246248
@Override
247249
public boolean equals(Object o) {
248-
if (this == o) {
249-
return true;
250-
}
251-
if (!(o instanceof SchemaLookupKey)) {
250+
if (o == null || getClass() != o.getClass()) {
252251
return false;
253252
}
254-
SchemaLookupKey other = (SchemaLookupKey) o;
255-
return this.parentSchema == other.parentSchema && this.attributeName.equals(other.attributeName);
253+
SchemaLookupKey that = (SchemaLookupKey) o;
254+
return Objects.equals(parentSchema, that.parentSchema) && Objects.equals(attributeName, that.attributeName);
256255
}
257256

258257
@Override
259258
public int hashCode() {
260-
return hash;
259+
return 31 * System.identityHashCode(parentSchema) + (attributeName == null ? 0 : attributeName.hashCode());
261260
}
262261
}
263262
}

0 commit comments

Comments
 (0)