Skip to content

Commit

Permalink
feat(core): Relationships auto-configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
JoseLion committed Feb 26, 2024
1 parent b501990 commit 9220c3b
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.github.joselion.springr2dbcrelationships;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;

import lombok.extern.slf4j.Slf4j;

/**
* Relationships autoconfiguration.
*/
@Slf4j
@Configuration
public class RelationshipsAutoConfiguration {

/**
* Default configuration constructor.
*/
protected RelationshipsAutoConfiguration() {
log.info("R2DBC Relationships auto-configuration loaded.");
}

/**
* Creates the {@link RelationshipsCallbacks} bean.
*
* @param <T> the type of the entity in the callback
* @param template the r2dbc entity template
* @param context the Spring application context
* @return the relationship callbacks bean
*/
@Bean
public <T> RelationshipsCallbacks<T> relationshipsCallbacks(
final @Lazy R2dbcEntityTemplate template,
final @Lazy ApplicationContext context
) {
return new RelationshipsCallbacks<>(template, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@

import org.reactivestreams.Publisher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.r2dbc.mapping.OutboundRow;
import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback;
import org.springframework.data.r2dbc.mapping.event.AfterSaveCallback;
import org.springframework.data.r2dbc.mapping.event.BeforeConvertCallback;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.stereotype.Component;

import io.github.joselion.springr2dbcrelationships.annotations.ManyToMany;
import io.github.joselion.springr2dbcrelationships.annotations.ManyToOne;
Expand All @@ -43,10 +41,9 @@
* @param template the r2dbc entity template
* @param context the Spring application context
*/
@Component
public record RelationshipCallbacks<T>(
@Lazy R2dbcEntityTemplate template,
@Lazy ApplicationContext context
public record RelationshipsCallbacks<T>(
R2dbcEntityTemplate template,
ApplicationContext context
) implements AfterConvertCallback<T>, AfterSaveCallback<T>, BeforeConvertCallback<T> {

@Override
Expand Down Expand Up @@ -163,19 +160,19 @@ public Publisher<T> onBeforeConvert(final T entity, final SqlIdentifier table) {
private UnaryOperator<Context> addToContextStack(final T entity) {
return ctx -> {
final var typeName = entity.getClass().getName();
final var stack = ctx.<List<String>>getOrEmpty(RelationshipCallbacks.class)
final var stack = ctx.<List<String>>getOrEmpty(RelationshipsCallbacks.class)
.map(List::stream)
.map(prev -> Stream.concat(prev, Stream.of(typeName)))
.map(Stream::toList)
.orElse(List.of(typeName));

return ctx.put(RelationshipCallbacks.class, stack);
return ctx.put(RelationshipsCallbacks.class, stack);
};
}

private <S> Mono<S> checkingCycles(final S data) {
return Mono.deferContextual(ctx -> {
final var stack = ctx.<List<String>>getOrEmpty(RelationshipCallbacks.class);
final var stack = ctx.<List<String>>getOrEmpty(RelationshipsCallbacks.class);

return Mono.justOrEmpty(stack)
.defaultIfEmpty(List.of())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback;
import org.springframework.data.relational.core.sql.SqlIdentifier;

import io.github.joselion.springr2dbcrelationships.RelationshipCallbacks;
import io.github.joselion.springr2dbcrelationships.RelationshipsCallbacks;
import io.github.joselion.springr2dbcrelationships.annotations.ManyToMany;
import io.github.joselion.springr2dbcrelationships.annotations.OneToMany;
import io.github.joselion.springr2dbcrelationships.exceptions.RelationshipException;
Expand Down Expand Up @@ -237,7 +237,7 @@ private Mono<String> findJoinTable(final Field field) {

private <S> Mono<S> checkingBackRef(final Class<?> type, final S value) {
return Mono.deferContextual(ctx -> {
final var stack = ctx.<List<String>>getOrEmpty(RelationshipCallbacks.class);
final var stack = ctx.<List<String>>getOrEmpty(RelationshipsCallbacks.class);

return Mono.justOrEmpty(stack)
.defaultIfEmpty(List.of())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.github.joselion.springr2dbcrelationships.RelationshipAutoConfiguration
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
final var table = SqlIdentifier.unquoted("test_entity");
final var template = mock(R2dbcEntityTemplate.class);
final var context = mock(ApplicationContext.class);
final var callbacks = new RelationshipCallbacks<>(template, context);
final var callbacks = new RelationshipsCallbacks<>(template, context);
final var publisher = callbacks.onAfterConvert(entity, table);

Mono.from(publisher)
.as(StepVerifier::create)
.expectAccessibleContext()
.contains(RelationshipCallbacks.class, List.of(TestEntity.class.getName()))
.contains(RelationshipsCallbacks.class, List.of(TestEntity.class.getName()))
.then()
.expectNext(entity)
.verifyComplete();
Expand Down

0 comments on commit 9220c3b

Please sign in to comment.