Move off RowMetadata.getColumnNames(…) in preparation for R2DBC 0.9.

Closes #683
This commit is contained in:
Mark Paluch
2021-11-10 14:34:30 +01:00
parent c8ef7b4076
commit d5aea5203c
5 changed files with 85 additions and 28 deletions

View File

@@ -15,12 +15,14 @@
*/
package org.springframework.data.r2dbc.convert;
import io.r2dbc.spi.ColumnMetadata;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
@@ -163,7 +165,7 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R
try {
Object value = null;
if (metadata == null || metadata.getColumnNames().contains(identifier)) {
if (metadata == null || RowMetadataUtils.containsColumn(metadata, identifier)) {
value = row.get(identifier);
}
@@ -187,6 +189,7 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R
}
}
public Object readValue(@Nullable Object value, TypeInformation<?> type) {
if (null == value) {
@@ -624,17 +627,8 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R
private boolean potentiallySetId(Row row, RowMetadata metadata, PersistentPropertyAccessor<?> propertyAccessor,
RelationalPersistentProperty idProperty) {
Collection<String> columns = metadata.getColumnNames();
Object generatedIdValue = null;
String idColumnName = idProperty.getColumnName().getReference();
if (columns.contains(idColumnName)) {
generatedIdValue = row.get(idColumnName);
} else if (columns.size() == 1) {
String key = columns.iterator().next();
generatedIdValue = row.get(key);
}
Object generatedIdValue = extractGeneratedIdentifier(row, metadata, idColumnName);
if (generatedIdValue == null) {
return false;
@@ -646,6 +640,24 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R
return true;
}
@Nullable
private Object extractGeneratedIdentifier(Row row, RowMetadata metadata, String idColumnName) {
if (RowMetadataUtils.containsColumn(metadata, idColumnName)) {
return row.get(idColumnName);
}
Iterable<? extends ColumnMetadata> columns = metadata.getColumnMetadatas();
Iterator<? extends ColumnMetadata> it = columns.iterator();
if (it.hasNext()) {
ColumnMetadata column = it.next();
return row.get(column.getName());
}
return null;
}
private <R> RelationalPersistentEntity<R> getRequiredPersistentEntity(Class<R> type) {
return (RelationalPersistentEntity<R>) getMappingContext().getRequiredPersistentEntity(type);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.r2dbc.convert;
import io.r2dbc.spi.ColumnMetadata;
import io.r2dbc.spi.RowMetadata;
/**
* Utility methods for {@link io.r2dbc.spi.RowMetadata}
*
* @author Mark Paluch
* @since 1.3.7
*/
class RowMetadataUtils {
/**
* Check whether the column {@code name} is contained in {@link RowMetadata}. The check happens case-insensitive.
*
* @param metadata the metadata object to inspect.
* @param name column name.
* @return {@code true} if the metadata contains the column {@code name}.
*/
public static boolean containsColumn(RowMetadata metadata, String name) {
for (ColumnMetadata columnMetadata : metadata.getColumnMetadatas()) {
if (name.equalsIgnoreCase(columnMetadata.getName())) {
return true;
}
}
return false;
}
}

View File

@@ -44,7 +44,7 @@ class RowPropertyAccessor implements PropertyAccessor {
@Override
public boolean canRead(EvaluationContext context, @Nullable Object target, String name) {
return rowMetadata != null && target != null && rowMetadata.getColumnNames().contains(name);
return rowMetadata != null && target != null && RowMetadataUtils.containsColumn(rowMetadata, name);
}
@Override

View File

@@ -5,14 +5,14 @@ import static org.mockito.Mockito.*;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import io.r2dbc.spi.test.MockColumnMetadata;
import io.r2dbc.spi.test.MockRowMetadata;
import lombok.RequiredArgsConstructor;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
@@ -32,15 +32,15 @@ public class EntityRowMapperUnitTests {
DefaultReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(PostgresDialect.INSTANCE);
Row rowMock = mock(Row.class);
RowMetadata metadata = mock(RowMetadata.class);
Collection<String> columns = mock(Collection.class);
@BeforeEach
public void before() {
when(columns.contains(anyString())).thenReturn(true);
when(metadata.getColumnNames()).thenReturn(columns);
}
RowMetadata metadata = MockRowMetadata.builder()
.columnMetadata(MockColumnMetadata.builder().name("integer_set").build())
.columnMetadata(MockColumnMetadata.builder().name("boxed_integers").build())
.columnMetadata(MockColumnMetadata.builder().name("primitive_integers").build())
.columnMetadata(MockColumnMetadata.builder().name("enum_array").build())
.columnMetadata(MockColumnMetadata.builder().name("set_of_enum").build())
.columnMetadata(MockColumnMetadata.builder().name("enum_set").build())
.columnMetadata(MockColumnMetadata.builder().name("id").build())
.columnMetadata(MockColumnMetadata.builder().name("ids").build()).build();
@Test // gh-22
public void shouldMapSimpleEntity() {

View File

@@ -20,6 +20,8 @@ import static org.mockito.Mockito.*;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import io.r2dbc.spi.test.MockColumnMetadata;
import io.r2dbc.spi.test.MockRowMetadata;
import lombok.Data;
import java.math.BigDecimal;
@@ -29,7 +31,6 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Function;
@@ -196,10 +197,8 @@ public abstract class ReactiveDataAccessStrategyTestSupport {
ReactiveDataAccessStrategy strategy = getStrategy();
Row rowMock = mock(Row.class);
RowMetadata metadataMock = mock(RowMetadata.class);
Collection<String> columnNames = mock(Collection.class);
when(metadataMock.getColumnNames()).thenReturn(columnNames);
when(columnNames.contains(fieldname)).thenReturn(true);
RowMetadata metadataMock = MockRowMetadata.builder()
.columnMetadata(MockColumnMetadata.builder().name(fieldname).build()).build();
PrimitiveTypes toSave = new PrimitiveTypes();
setter.accept(toSave, testValue);