protected void performMigration(final DataSource dataSource) {

        final AtomicBoolean isDbUsingFlyWay = new AtomicBoolean(false);
        LOGGER.info("Testing installed Stroom schema version");

        final Optional<Version> optVersion = establishDbSchemaVersion(dataSource, isDbUsingFlyWay);

        optVersion.ifPresentOrElse(
                version -> LOGGER.info("Detected current Stroom version is v" + version.toString()),
                () -> LOGGER.info("This is an installation of v7.0 or greater. Legacy migrations won't be applied.")
        );

        // Only apply legacy migrations if this is an old DB.
        if (optVersion.isPresent()) {
            Optional<String> optBaselineVersionAsString = optVersion.flatMap(version -> {
                if (!isDbUsingFlyWay.get()) {
                    if (version.getMajor() == 4 && version.getMinor() == 0 && version.getPatch() >= 60) {
                        // If Stroom is currently at v4.0.60+ then tell FlyWay to baseline at that version.
                        return Optional.of("4.0.60");
                    } else {
                        final String message =
                                "The current Stroom version cannot be upgraded to v5+. " +
                                        "You must be on v4.0.60 or later.";
                        LOGGER.error(MarkerFactory.getMarker("FATAL"), message);
                        throw new RuntimeException(message);
                    }
                } else {
                    return Optional.empty();
                }
            });

            final FluentConfiguration configuration = Flyway.configure()
                    .dataSource(dataSource)
                    .locations(FLYWAY_LOCATIONS)
                    .table(FLYWAY_TABLE)
                    .baselineOnMigrate(true);

            optBaselineVersionAsString.ifPresent(configuration::baselineVersion);

            final Flyway flyway = configuration.load();

            optBaselineVersionAsString.ifPresent(ver ->
                    flyway.baseline());

            migrateDatabase(flyway);
        }
    }
Configures anything related to persistence, e.g. transaction management, the
entity manager factory, data sources.
<p>
This does not extend {@link stroom.db.util.AbstractDataSourceProviderModule} as the core migrations
are special and need to happen first before all the other migrations. {@link ForceLegacyMigration} is
used to achieve this by making all other datasource providers depend on {@link ForceLegacyMigration}.
stroom-legacy/stroom-legacy-db-migration/src/main/java/stroom/legacy/db/LegacyDbModule.java