@Override
    public synchronized <R> void fetch(final List<Column> columns,
                                       final OffsetRange range,
                                       final OpenGroups openGroups,
                                       final TimeFilter timeFilter,
                                       final ItemMapper<R> mapper,
                                       final Consumer<R> resultConsumer,
                                       final Consumer<Long> totalRowCountConsumer) {
        // Update our sort columns if needed.
        compiledSorters.update(columns);

        final OffsetRange enforcedRange = Optional
                .ofNullable(range)
                .orElse(OffsetRange.ZERO_100);

        SearchProgressLog.increment(queryKey, SearchPhase.LMDB_DATA_STORE_GET);

        if (env.isClosed()) {
            // If we query LMDB after the env has been closed then we are likely to crash the JVM
            // see https://github.com/lmdbjava/lmdbjava/issues/185
            LOGGER.debug(() -> "fetch called (queryKey =" +
                               queryKey +
                               ", componentId=" +
                               componentId +
                               ") after store has been shut down");

        } else {
            env.read(readTxn ->
                    SimpleMetrics.measure("fetch", () -> {
                        try {
                            final FetchState fetchState = new FetchState();
                            fetchState.countRows = totalRowCountConsumer != null;
                            fetchState.reachedRowLimit = fetchState.length >= enforcedRange.getLength();
                            fetchState.keepGoing = fetchState.justCount || !fetchState.reachedRowLimit;

                            final LmdbReadContext readContext =
                                    new LmdbReadContext(LmdbDataStore.this, db, readTxn, timeFilter);

                            getChildren(
                                    readContext,
                                    Key.ROOT_KEY,
                                    0,
                                    maxResultSizes.size(0),
                                    false,
                                    openGroups,
                                    timeFilter,
                                    mapper,
                                    enforcedRange,
                                    fetchState,
                                    resultConsumer);

                            if (totalRowCountConsumer != null) {
                                totalRowCountConsumer.accept(fetchState.totalRowCount);
                            }
                        } catch (final Throwable e) {
                            LOGGER.error(e::getMessage, e);
                        }
                    }));
        }
    }
Write data from the data store to an output removing them from the datastore as we go as they will be transferred
to another store.

@param output The output to write to.
stroom-query/stroom-query-common/src/main/java/stroom/query/common/v2/LmdbDataStore.java