Skip to content

Commit 099c890

Browse files
committed
Polishing.
Introduce ColumnInfos.reduce(…) operation.
1 parent 5527960 commit 099c890

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/Identifier.java

+20
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,25 @@ public static Identifier from(Map<SqlIdentifier, Object> map) {
9999
return new Identifier(Collections.unmodifiableList(values));
100100
}
101101

102+
/**
103+
* Creates a new {@link Identifier} from the current instance and sets the value from {@link Identifier}. Existing key
104+
* definitions for {@code name} are overwritten if they already exist.
105+
*
106+
* @param identifier the identifier to append.
107+
* @return the {@link Identifier} containing all existing keys and the key part for {@code name}, {@code value}, and a
108+
* {@link Class target type}.
109+
* @since 3.5
110+
*/
111+
public Identifier withPart(Identifier identifier) {
112+
113+
Identifier result = this;
114+
for (SingleIdentifierValue part : identifier.getParts()) {
115+
result = result.withPart(part.getName(), part.getValue(), part.getTargetType());
116+
}
117+
118+
return result;
119+
}
120+
102121
/**
103122
* Creates a new {@link Identifier} from the current instance and sets the value for {@code key}. Existing key
104123
* definitions for {@code name} are overwritten if they already exist.
@@ -188,6 +207,7 @@ public Object get(SqlIdentifier columnName) {
188207
return null;
189208
}
190209

210+
191211
/**
192212
* A single value of an Identifier consisting of the column name, the value and the target type which is to be used to
193213
* store the element in the database.

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/JdbcIdentifierBuilder.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public static JdbcIdentifierBuilder empty() {
4848
public static JdbcIdentifierBuilder forBackReferences(JdbcConverter converter, AggregatePath path, Object value) {
4949

5050
RelationalPersistentProperty idProperty = path.getIdDefiningParentPath().getRequiredIdProperty();
51-
AggregatePath.ColumnInfos reverseColumnInfos = path.getTableInfo().reverseColumnInfos();
51+
AggregatePath.ColumnInfos infos = path.getTableInfo().reverseColumnInfos();
5252

5353
// create property accessor
5454
RelationalMappingContext mappingContext = converter.getMappingContext();
@@ -62,16 +62,14 @@ public static JdbcIdentifierBuilder forBackReferences(JdbcConverter converter, A
6262
valueProvider = ap -> propertyPathAccessor.getProperty(ap.getRequiredPersistentPropertyPath());
6363
}
6464

65-
final Identifier[] identifierHolder = new Identifier[] { Identifier.empty() };
66-
67-
reverseColumnInfos.forEach((ap, ci) -> {
65+
Identifier identifierHolder = infos.reduce(Identifier.empty(), (ap, ci) -> {
6866

6967
RelationalPersistentProperty property = ap.getRequiredLeafProperty();
70-
identifierHolder[0] = identifierHolder[0].withPart(ci.name(), valueProvider.apply(ap),
68+
return Identifier.of(ci.name(), valueProvider.apply(ap),
7169
converter.getColumnType(property));
72-
});
70+
}, Identifier::withPart);
7371

74-
return new JdbcIdentifierBuilder(identifierHolder[0]);
72+
return new JdbcIdentifierBuilder(identifierHolder);
7573
}
7674

7775
/**

spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/AggregatePath.java

+33-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.TreeMap;
2424
import java.util.function.BiConsumer;
2525
import java.util.function.BiFunction;
26+
import java.util.function.BinaryOperator;
2627
import java.util.function.Function;
2728
import java.util.function.Predicate;
2829
import java.util.stream.Stream;
@@ -475,14 +476,44 @@ public <T> List<T> toList(Function<ColumnInfo, T> mapper) {
475476
return columnInfos.values().stream().map(mapper).toList();
476477
}
477478

479+
/**
480+
* Performs a {@link Stream#reduce(Object, BiFunction, BinaryOperator)} on {@link ColumnInfo} and
481+
* {@link AggregatePath} to reduce the results into a single {@code T} return value.
482+
* <p>
483+
* If {@code ColumnInfos} is empty, then {@code identity} is returned. Without invoking {@code combiner}. The
484+
* {@link BinaryOperator combiner} is called with the current state (or initial {@code identity}) and the
485+
* accumulated {@code T} state to combine both into a single return value.
486+
*
487+
* @param identity the identity (initial) value for the combiner function.
488+
* @param accumulator an associative, non-interfering (free of side effects), stateless function for incorporating
489+
* an additional element into a result.
490+
* @param combiner an associative, non-interfering, stateless function for combining two values, which must be
491+
* compatible with the {@code accumulator} function.
492+
* @return result of the function.
493+
* @param <T> type of the result.
494+
* @since 3.5
495+
*/
496+
public <T> T reduce(T identity, BiFunction<AggregatePath, ColumnInfo, T> accumulator, BinaryOperator<T> combiner) {
497+
498+
T result = identity;
499+
500+
for (Map.Entry<AggregatePath, ColumnInfo> entry : columnInfos.entrySet()) {
501+
502+
T mapped = accumulator.apply(entry.getKey(), entry.getValue());
503+
result = combiner.apply(result, mapped);
504+
}
505+
506+
return result;
507+
}
508+
478509
public void forEach(BiConsumer<AggregatePath, ColumnInfo> consumer) {
479510
columnInfos.forEach(consumer);
480511
}
481512

482-
public <T> T any(BiFunction<AggregatePath, ColumnInfo, T> consumer) {
513+
public <T> T any(BiFunction<AggregatePath, ColumnInfo, T> mapper) {
483514

484515
Map.Entry<AggregatePath, ColumnInfo> any = columnInfos.entrySet().iterator().next();
485-
return consumer.apply(any.getKey(), any.getValue());
516+
return mapper.apply(any.getKey(), any.getValue());
486517
}
487518

488519
public ColumnInfo get(AggregatePath path) {

0 commit comments

Comments
 (0)