All Downloads are FREE. Search and download functionalities are using the official Maven repository.

name.nkonev.r2dbc.migrate.autoconfigure.R2dbcAutoConfiguration Maven / Gradle / Ivy

There is a newer version: 0.0.23
Show newest version
package name.nkonev.r2dbc.migrate.autoconfigure;

import io.r2dbc.spi.Connection;
import io.r2dbc.spi.ConnectionFactory;
import name.nkonev.r2dbc.migrate.core.MSSqlQueries;
import name.nkonev.r2dbc.migrate.core.PostgreSqlQueries;
import name.nkonev.r2dbc.migrate.core.R2dbcMigrate;
import name.nkonev.r2dbc.migrate.core.SqlQueries;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBuilder;
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.boot.autoconfigure.r2dbc.EmbeddedDatabaseConnection;
import org.springframework.boot.autoconfigure.r2dbc.R2dbcProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

@Configuration
@EnableConfigurationProperties(R2dbcAutoConfiguration.SpringBootR2dbcMigrateProperties.class)
public class R2dbcAutoConfiguration {

    private static final String MIGRATE_BEAN_NAME = "r2dbcMigrate";

    private static final Logger LOGGER = LoggerFactory.getLogger(R2dbcAutoConfiguration.class);

    // declares that ConnectionFactory depends on r2dbcMigrate
    @Configuration
    public static class R2dbcConnectionFactoryDependsOnBeanFactoryPostProcessor extends AbstractDependsOnBeanFactoryPostProcessor {

        protected R2dbcConnectionFactoryDependsOnBeanFactoryPostProcessor() {
            super(ConnectionFactory.class, MIGRATE_BEAN_NAME);
        }
    }

    // copy-paste from org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryConfigurations
    protected static ConnectionFactory createConnectionFactory(R2dbcProperties properties, ClassLoader classLoader,
                                                               List optionsCustomizers) {
        return ConnectionFactoryBuilder.of(properties, () -> EmbeddedDatabaseConnection.get(classLoader))
                .configure((options) -> {
                    for (ConnectionFactoryOptionsBuilderCustomizer optionsCustomizer : optionsCustomizers) {
                        optionsCustomizer.customize(options);
                    }
                }).build();
    }

    // Connection supplier creating new Connection from new ConnectionFactory.
    // It's intentionally behaviour, see explanation in R2dbcMigrate#migrate
    protected static Mono makeConnectionMono(R2dbcProperties properties,
                                                         ResourceLoader resourceLoader,
                                                         ObjectProvider customizers) {
        LOGGER.debug("Supplying connection");
        return Mono.from(createConnectionFactory(properties, resourceLoader.getClassLoader(), customizers.orderedStream().collect(Collectors.toList())).create());
    }

    @ConfigurationProperties("r2dbc.migrate")
    public static class SpringBootR2dbcMigrateProperties extends R2dbcMigrate.MigrateProperties {

    }

    public static class R2dbcMigrateBlockingInvoker {
        private R2dbcProperties r2dbcProperties;
        private ResourceLoader resourceLoader;
        private ObjectProvider customizers;
        private R2dbcMigrate.MigrateProperties properties;

        public R2dbcMigrateBlockingInvoker(R2dbcProperties r2dbcProperties, ResourceLoader resourceLoader,
                                           ObjectProvider customizers,
                                           R2dbcMigrate.MigrateProperties properties) {
            this.r2dbcProperties = r2dbcProperties;
            this.resourceLoader = resourceLoader;
            this.customizers = customizers;
            this.properties = properties;
        }

        public void migrate() {
            R2dbcMigrate.Hooks hooks = new R2dbcMigrate.Hooks() {
                @Override
                public BiFunction getSqlQueriesFunction() {
                    if (properties.getDialect() == null) {
                        return (migrateProperties, connection) -> {
                            String databaseProductName = connection.getMetadata().getDatabaseProductName();
                            if (databaseProductName.startsWith("PostgreSQL")) {
                                return new PostgreSqlQueries();
                            } else if (databaseProductName.startsWith("Microsoft SQL Server")) {
                                return new MSSqlQueries();
                            } else {
                                return super.getSqlQueriesFunction().apply(migrateProperties, connection);
                            }
                        };
                    } else {
                        return super.getSqlQueriesFunction();
                    }
                }
            };
            R2dbcMigrate.migrate(() -> makeConnectionMono(r2dbcProperties, resourceLoader, customizers), properties, hooks).block();
            LOGGER.info("End of migration");
        }

    }

    @Bean(name = MIGRATE_BEAN_NAME, initMethod = "migrate")
    public R2dbcMigrateBlockingInvoker r2dbcMigrate(R2dbcProperties r2dbcProperties, ResourceLoader resourceLoader,
                                                    ObjectProvider customizers,
                                                    SpringBootR2dbcMigrateProperties properties) {
        return new R2dbcMigrateBlockingInvoker(r2dbcProperties, resourceLoader, customizers, properties);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy