net.lecousin.reactive.data.relational.LcReactiveDataRelationalClient Maven / Gradle / Ivy
package net.lecousin.reactive.data.relational;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.reactivestreams.Publisher;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.lang.Nullable;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.stereotype.Component;
import net.lecousin.reactive.data.relational.enhance.EntityState;
import net.lecousin.reactive.data.relational.mapping.LcEntityReader;
import net.lecousin.reactive.data.relational.mapping.LcMappingR2dbcConverter;
import net.lecousin.reactive.data.relational.mapping.LcReactiveDataAccessStrategy;
import net.lecousin.reactive.data.relational.model.EntityCache;
import net.lecousin.reactive.data.relational.model.LcEntityTypeInfo;
import net.lecousin.reactive.data.relational.model.ModelUtils;
import net.lecousin.reactive.data.relational.query.SelectExecution;
import net.lecousin.reactive.data.relational.query.SelectQuery;
import net.lecousin.reactive.data.relational.query.criteria.Criteria;
import net.lecousin.reactive.data.relational.query.operation.Operation;
import net.lecousin.reactive.data.relational.schema.RelationalDatabaseSchema;
import net.lecousin.reactive.data.relational.schema.SchemaBuilderFromEntities;
import net.lecousin.reactive.data.relational.schema.dialect.RelationalDatabaseSchemaDialect;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Component
public class LcReactiveDataRelationalClient {
public static final Log logger = LogFactory.getLog(LcReactiveDataRelationalClient.class);
private static final String QUERY_ENTITY_NAME = "entity";
private DatabaseClient client;
private MappingContext, ? extends RelationalPersistentProperty> mappingContext;
private RelationalDatabaseSchemaDialect schemaDialect;
private LcReactiveDataAccessStrategy dataAccess;
private LcMappingR2dbcConverter mapper;
public LcReactiveDataRelationalClient(
DatabaseClient client,
MappingContext, ? extends RelationalPersistentProperty> mappingContext,
RelationalDatabaseSchemaDialect schemaDialect,
LcReactiveDataAccessStrategy dataAccess,
LcMappingR2dbcConverter mapper
) {
this.client = client;
this.mappingContext = mappingContext;
this.schemaDialect = schemaDialect;
this.dataAccess = dataAccess;
this.mapper = mapper;
this.mapper.setLcClient(this);
// ensure all declared entities have been detected by Spring
for (Class> type : LcEntityTypeInfo.getClasses())
mappingContext.getPersistentEntity(type);
}
public DatabaseClient getSpringClient() {
return client;
}
public LcMappingR2dbcConverter getMapper() {
return mapper;
}
@SuppressWarnings("java:S1452") // usage of generic wildcard type
public MappingContext, ? extends RelationalPersistentProperty> getMappingContext() {
return mappingContext;
}
public LcReactiveDataAccessStrategy getDataAccess() {
return dataAccess;
}
public RelationalDatabaseSchemaDialect getSchemaDialect() {
return schemaDialect;
}
public R2dbcDialect getDialect() {
return dataAccess.getDialect();
}
public Mono dropSchemaContent(RelationalDatabaseSchema schema) {
return schemaDialect.dropSchemaContent(schema).execute(this);
}
public Mono createSchemaContent(RelationalDatabaseSchema schema) {
return schemaDialect.createSchemaContent(schema).execute(this);
}
public Mono dropCreateSchemaContent(RelationalDatabaseSchema schema) {
return dropSchemaContent(schema).then(createSchemaContent(schema));
}
public RelationalDatabaseSchema buildSchemaFromEntities() {
return buildSchemaFromEntities(LcEntityTypeInfo.getClasses());
}
public RelationalDatabaseSchema buildSchemaFromEntities(Collection> classes) {
return new SchemaBuilderFromEntities(this).build(classes);
}
public Mono save(T entity) {
try {
@SuppressWarnings("unchecked")
RelationalPersistentEntity entityType = (RelationalPersistentEntity) mappingContext.getRequiredPersistentEntity(entity.getClass());
Operation op = new Operation(this);
op.addToSave(entity, entityType, null, null);
return op.execute().thenReturn(entity);
} catch (Exception e) {
return Mono.error(e);
}
}
public Flux save(Iterable entities) {
try {
Iterator it = entities.iterator();
if (!it.hasNext())
return Flux.empty();
T instance = it.next();
@SuppressWarnings("unchecked")
RelationalPersistentEntity entityType = (RelationalPersistentEntity) mappingContext.getRequiredPersistentEntity(instance.getClass());
Operation op = new Operation(this);
op.addToSave(instance, entityType, null, null);
while (it.hasNext())
op.addToSave(it.next(), entityType, null, null);
return op.execute().thenMany(Flux.fromIterable(entities));
} catch (Exception e) {
return Flux.error(e);
}
}
public Flux save(Publisher publisher) {
Operation op = new Operation(this);
List list = new LinkedList<>();
return Flux.from(publisher)
.doOnNext(instance -> {
op.addToSave(instance, null, null, null);
list.add(instance);
})
.then(Mono.fromCallable(op::execute))
.flatMap(m -> m)
.thenReturn(list)
.flatMapMany(Flux::fromIterable);
}
public Mono saveAll(Iterable
© 2015 - 2024 Weber Informatics LLC | Privacy Policy