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

fr.ght1pc9kc.testy.jooq.WithDatabaseLoaded Maven / Gradle / Ivy

The newest version!
package fr.ght1pc9kc.testy.jooq;

import lombok.AllArgsConstructor;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.Location;
import org.flywaydb.core.api.configuration.ClassicConfiguration;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;

import javax.sql.DataSource;
import java.util.Objects;
import java.util.Optional;

/**
 * 

This extension depends on a {@link DatasourceExtension} and runs a Flyway * migration on the related DB catalog.

* *

By default, the SQL scripts have to be located into {@code db.migration.} in the classpath, where {@code } * is the name of DataSource catalog. The names of the SQL files shall match * Flyway naming convention.

* *

The SQL scripts are run **before all the test methods**. They are expected to be used to create the database schema.

* *

 * private static final WithInMemoryDatasource wDataSource = WithInMemoryDatasource.builder()
 *         .setCatalog("my_catalog")
 *         .build();
 *
 * // SQL files shall be located in classpath:db.migration.my_catalog
 * private static final WithDatabaseLoaded wDatabaseLoaded = WithDatabaseLoaded.builder()
 *         .setDatasourceExtension(wDataSource)
 *         .build();
 *
 * {@literal @}RegisterExtension
 * static final ChainedExtension chain = ChainedExtension
 *         .outer(wDataSource)
 *         .append(wDatabaseLoaded)
 *         .register();
 * 
*/ @AllArgsConstructor public final class WithDatabaseLoaded implements BeforeAllCallback, BeforeEachCallback { private static final String P_LOADED = "dbLoaded_"; private final DatasourceExtension wDatasource; private final @Nullable Location location; @Override public void beforeAll(ExtensionContext context) { String catalog = getContextCatalog(context); DataSource dataSource = Objects.requireNonNull(wDatasource.getDataSource(context), "DataSource not found in context Store !"); Location migrationsLocation = Optional.ofNullable(location) .orElseGet(() -> new Location("classpath:db/migration/" + catalog)); Flyway flyway = Flyway.configure() .cleanDisabled(false) .dataSource(dataSource) .schemas(catalog) .placeholderReplacement(false) .locations(migrationsLocation) .load(); flyway.clean(); flyway.migrate(); getStore(context).put(P_LOADED + catalog, true); } @Override public void beforeEach(ExtensionContext context) { String catalog = getContextCatalog(context); if (getStore(context).get(P_LOADED + catalog) == null) { throw new IllegalStateException(getClass().getName() + " must be static and package-protected !"); } } private ExtensionContext.Store getStore(ExtensionContext context) { return context.getStore(ExtensionContext.Namespace.create(getClass().getName())); } private String getContextCatalog(ExtensionContext context) { return Objects.requireNonNull(wDatasource.getCatalog(context), "Catalog not found in context Store !"); } public static WithDatabaseLoadedBuilder builder() { return new WithDatabaseLoadedBuilder(); } /** * Builder for {@link WithDatabaseLoaded} */ public static class WithDatabaseLoadedBuilder { private DatasourceExtension wDatasource; private Location location = null; /** *

Allow to link the {@link DatasourceExtension} with the {@link WithDatabaseLoaded}. The Flyway migrations * was applied to the {@link DataSource} created by this extension.

*

This setter is mandatory.

* * @param wDatasource The linked {@link DataSource} extension * @return The current builder */ public WithDatabaseLoadedBuilder setDatasourceExtension(DatasourceExtension wDatasource) { this.wDatasource = wDatasource; return this; } /** *

Allow to set the migrations location. To indicate Flyway where to found SQL files.

* *

By default, the {@link WithDatabaseLoaded} use {@code db/migration/catalog}, where catalog was the * schema given by the {@link DataSource} context

* *

This method was not compatible with {@link #useFlywayDefaultLocation()}

* * @param location The migration files location. * @return The current builder */ public WithDatabaseLoadedBuilder setMigrationsLocation(String location) { this.location = new Location(location); return this; } /** *

Use the Flyway default migrations location instead a migration with catalog name.

* *

By default, the {@link WithDatabaseLoaded} use {@code db/migration/catalog}, where catalog was the * schema given by the {@link DataSource} context

* *

This method was not compatible with {@link #setMigrationsLocation(String)}

* * @return The current builder */ public WithDatabaseLoadedBuilder useFlywayDefaultLocation() { this.location = new ClassicConfiguration().getLocations()[0]; return this; } /** * Build the {@link WithDatabaseLoaded} extension * * @return The extension */ public WithDatabaseLoaded build() { Objects.requireNonNull(wDatasource, "A DataSource extension was mandatory !"); return new WithDatabaseLoaded(wDatasource, location); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy