@NotNull
    private Optional<Version> establishDbSchemaVersion(final DataSource dataSource,
                                                       final AtomicBoolean isDbUsingFlyWay) {
        Optional<Version> optVersion;

        try (final Connection connection = dataSource.getConnection()) {

            isDbUsingFlyWay.set(DbUtil.doesTableExist(connection, "schema_version"));

            // Try a number of approaches to determine the version of the existing DB schema
            final Stream<Function<Connection, Optional<Version>>> versionFunctions = Stream.of(
                    this::getVersionFromSchemaVersionTable,
                    this::getVersionFromStroomVerTable,
                    this::getVersionFromPresenceOfFdTable,
                    this::getVersionFromPresenceOfFeedTable);

            optVersion = versionFunctions
                    .map(func -> func.apply(connection))
                    .filter(Optional::isPresent)
                    .map(Optional::get)
                    .findFirst();

        } catch (final SQLException e) {
            LOGGER.error(MarkerFactory.getMarker("FATAL"), e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
        return optVersion;
    }
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