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

org.javers.repository.sql.finders.CdoSnapshotFinder Maven / Gradle / Ivy

There is a newer version: 7.6.2
Show newest version
package org.javers.repository.sql.finders;

import java.util.Optional;

import org.javers.common.collections.Lists;
import org.javers.common.collections.Pair;
import org.javers.common.collections.Sets;
import org.javers.core.json.CdoSnapshotSerialized;
import org.javers.core.json.JsonConverter;
import org.javers.core.metamodel.object.CdoSnapshot;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.core.metamodel.type.EntityType;
import org.javers.core.metamodel.type.ManagedType;
import org.javers.repository.api.QueryParams;
import org.javers.repository.api.QueryParamsBuilder;
import org.javers.repository.api.SnapshotIdentifier;
import org.javers.repository.sql.repositories.GlobalIdRepository;
import org.javers.repository.sql.schema.TableNameProvider;
import org.polyjdbc.core.PolyJDBC;
import org.polyjdbc.core.query.Order;
import org.polyjdbc.core.query.SelectQuery;

import java.util.*;

import static org.javers.repository.sql.PolyUtil.queryForOptionalLong;
import static org.javers.repository.sql.schema.FixedSchemaFactory.*;

public class CdoSnapshotFinder {

    private final PolyJDBC polyJDBC;
    private final GlobalIdRepository globalIdRepository;
    private final CommitPropertyFinder commitPropertyFinder;
    private final CdoSnapshotMapper cdoSnapshotMapper;
    private final CdoSnapshotsEnricher cdoSnapshotsEnricher = new CdoSnapshotsEnricher();
    private JsonConverter jsonConverter;
    private final TableNameProvider tableNameProvider;

    public CdoSnapshotFinder(PolyJDBC polyJDBC, GlobalIdRepository globalIdRepository, CommitPropertyFinder commitPropertyFinder, TableNameProvider tableNameProvider) {
        this.polyJDBC = polyJDBC;
        this.globalIdRepository = globalIdRepository;
        this.commitPropertyFinder = commitPropertyFinder;
        this.cdoSnapshotMapper = new CdoSnapshotMapper();
        this.tableNameProvider = tableNameProvider;
    }

    public Optional getLatest(GlobalId globalId) {
        Optional globalIdPk = globalIdRepository.findGlobalIdPk(globalId);
        if (!globalIdPk.isPresent()){
            return Optional.empty();
        }

        return selectMaxSnapshotPrimaryKey(globalIdPk.get()).map(maxSnapshot -> {
            QueryParams oneItemLimit = QueryParamsBuilder.withLimit(1).build();
            return fetchCdoSnapshots(new SnapshotIdFilter(tableNameProvider, maxSnapshot), Optional.of(oneItemLimit)).get(0);
        });
    }

    public List getSnapshots(QueryParams queryParams) {
        return fetchCdoSnapshots(new AnySnapshotFilter(tableNameProvider), Optional.of(queryParams));
    }

    public List getSnapshots(Collection snapshotIdentifiers) {
        return fetchCdoSnapshots(new SnapshotIdentifiersFilter(tableNameProvider, globalIdRepository, snapshotIdentifiers), Optional.empty());
    }

    public List getStateHistory(Set managedTypes, QueryParams queryParams) {
        Set managedTypeNames = Sets.transform(managedTypes, managedType -> managedType.getName());
        ManagedClassFilter classFilter = new ManagedClassFilter(tableNameProvider, managedTypeNames, queryParams.isAggregate());
        return fetchCdoSnapshots(classFilter, Optional.of(queryParams));
    }

    public List getVOStateHistory(EntityType ownerEntity, String fragment, QueryParams queryParams) {
        VoOwnerEntityFilter voOwnerFilter = new VoOwnerEntityFilter(tableNameProvider, ownerEntity.getName(), fragment);
        return fetchCdoSnapshots(voOwnerFilter, Optional.of(queryParams));
    }

    public List getStateHistory(GlobalId globalId, QueryParams queryParams) {
        Optional globalIdPk = globalIdRepository.findGlobalIdPk(globalId);

        return globalIdPk.map(id ->
                fetchCdoSnapshots(new GlobalIdFilter(tableNameProvider, id, queryParams.isAggregate()), Optional.of(queryParams)))
                .orElse(Collections.emptyList());
    }

    private List fetchCdoSnapshots(SnapshotFilter snapshotFilter, Optional queryParams) {
        List> serializedSnapshots = queryForCdoSnapshotDTOs(snapshotFilter, queryParams);

        List commitPropertyDTOs =
                commitPropertyFinder.findCommitPropertiesOfSnaphots(Pair.collectRightAsSet(serializedSnapshots));

        cdoSnapshotsEnricher.enrichWithCommitProperties(serializedSnapshots, commitPropertyDTOs);

        return Lists.transform(serializedSnapshots,
                serializedSnapshot -> jsonConverter.fromSerializedSnapshot(serializedSnapshot.left()));
    }

    private List> queryForCdoSnapshotDTOs(SnapshotFilter snapshotFilter, Optional queryParams) {
        SelectQuery query =  polyJDBC.query().select(snapshotFilter.select());
        snapshotFilter.addFrom(query);
        snapshotFilter.addWhere(query);
        if (queryParams.isPresent()) {
            snapshotFilter.applyQueryParams(query, queryParams.get());
        }
        query.orderBy(SNAPSHOT_PK, Order.DESC);
        return polyJDBC.queryRunner().queryList(query, cdoSnapshotMapper);
    }

    private Optional selectMaxSnapshotPrimaryKey(long globalIdPk) {
        SelectQuery query = polyJDBC.query()
            .select("MAX(" + SNAPSHOT_PK + ")")
            .from(tableNameProvider.getSnapshotTableNameWithSchema())
            .where(SNAPSHOT_GLOBAL_ID_FK + " = :globalIdPk")
            .withArgument("globalIdPk", globalIdPk);

        Optional result = queryForOptionalLong(query, polyJDBC);

        if (result.isPresent() && result.get() == 0){
            return Optional.empty();
        }
        return result;
    }

    public void setJsonConverter(JsonConverter jsonConverter) {
        this.jsonConverter = jsonConverter;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy