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

com.github.molcikas.photon.query.PhotonAggregateQuery Maven / Gradle / Ivy

The newest version!
package com.github.molcikas.photon.query;

import com.github.molcikas.photon.Photon;
import com.github.molcikas.photon.PhotonEntityState;
import com.github.molcikas.photon.blueprints.AggregateBlueprint;
import com.github.molcikas.photon.blueprints.entity.EntityBlueprint;
import com.github.molcikas.photon.blueprints.entity.FieldBlueprint;
import com.github.molcikas.photon.blueprints.entity.FlattenedCollectionBlueprint;
import com.github.molcikas.photon.exceptions.PhotonException;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.util.*;
import java.util.stream.Collectors;

public class PhotonAggregateQuery
{
    private final AggregateBlueprint aggregateBlueprint;
    private final Connection connection;
    private final PhotonEntityState photonEntityState;
    private final Photon photon;
    private final List excludedFieldPaths;
    private boolean trackChanges = true;

    public PhotonAggregateQuery(
        AggregateBlueprint aggregateBlueprint,
        Connection connection,
        PhotonEntityState photonEntityState,
        Photon photon)
    {
        this.aggregateBlueprint = aggregateBlueprint;
        this.connection = connection;
        this.photonEntityState = photonEntityState;
        this.photon = photon;
        this.excludedFieldPaths = new ArrayList<>();
    }

    public PhotonAggregateQuery exclude(String fieldName)
    {
        if(StringUtils.isBlank(fieldName))
        {
            throw new PhotonException("Excluded field name cannot be blank.");
        }
        excludedFieldPaths.add(fieldName);
        return this;
    }

    public PhotonAggregateQuery noTracking()
    {
        this.trackChanges = false;
        return this;
    }

    /**
     * Fetch an aggregate by its id.
     *
     * @param id - The id
     * @return - The aggregate instance, or null if the aggregate was not found
     */
    public T fetchById(Object id)
    {
        List populatedAggregateRoots = getPopulatedAggregateRoots(Collections.singletonList(id), null, false);
        return populatedAggregateRoots.isEmpty() ? null : populatedAggregateRoots.get(0);
    }

    /**
     * Fetch a list of aggregates by ids.
     *
     * @param ids - The ids
     * @return - The aggregate instances
     */
    public List fetchByIds(Object... ids)
    {
        return fetchByIds(Arrays.asList(ids));
    }

    /**
     * Fetch a list of aggregates by ids.
     *
     * @param ids - The ids
     * @return - The aggregate instances
     */
    public List fetchByIds(List ids)
    {
        return getPopulatedAggregateRoots(ids, null, false);
    }

    /**
     * Fetch a list of aggregates from a query that selects a list of ids.
     *
     * @param selectSql - The parameterized SQL query for selecting a list of ids
     * @return - A filter query object that can be executed to return a list of aggregate ids to fetch
     */
    public PhotonAggregateFilterQuery whereIdIn(String selectSql)
    {
        return new PhotonAggregateFilterQuery<>(aggregateBlueprint, selectSql, false, connection, photon, this);
    }

    /**
     * Fetch a list of aggregates that meet a specified set of conditions. Only the WHERE clause needs to be specified,
     * not including the WHERE keyword.
     *
     * @param whereClause - The where clause for a parameterized SQL query
     * @return - A filter query object that can be executed to return a list of aggregates
     */
    public PhotonAggregateFilterQuery where(String whereClause)
    {
        return new PhotonAggregateFilterQuery<>(aggregateBlueprint, whereClause, true, connection, photon, this);
    }

    T fetchByIdsQuery(PhotonQuery photonQuery)
    {
        List populatedAggregateRoots =  getPopulatedAggregateRoots(null, photonQuery, true);
        return populatedAggregateRoots.isEmpty() ? null : populatedAggregateRoots.get(0);
    }

    T fetchByQuery(PhotonQuery photonQuery)
    {
        List populatedAggregateRoots =  getPopulatedAggregateRoots(null, photonQuery, false);
        return populatedAggregateRoots.isEmpty() ? null : populatedAggregateRoots.get(0);
    }

    List fetchListByIdsQuery(PhotonQuery photonQuery)
    {
        return getPopulatedAggregateRoots(null, photonQuery, true);
    }

    List fetchListByQuery(PhotonQuery photonQuery)
    {
        return getPopulatedAggregateRoots(null, photonQuery, false);
    }

    private List getPopulatedAggregateRoots(List ids, PhotonQuery photonQuery, boolean isQueryIdsOnly)
    {
        PopulatedEntityMap populatedEntityMap = new PopulatedEntityMap();

        for(EntityBlueprint entityBlueprint : aggregateBlueprint.getEntityBlueprints(excludedFieldPaths))
        {
            ids = executeQueryAndCreateEntityOrphans(populatedEntityMap, entityBlueprint, ids, photonQuery, isQueryIdsOnly);
        }

        populatedEntityMap.mapAllEntityInstanceChildren();

        if(trackChanges)
        {
            photonEntityState.track(populatedEntityMap);
        }

        return populatedEntityMap
            .getPopulatedEntitiesForBlueprint(aggregateBlueprint.getAggregateRootEntityBlueprint())
            .stream()
            .map(pe -> (T) pe.getEntityInstance())
            .collect(Collectors.toList());
    }

    private List executeQueryAndCreateEntityOrphans(
        PopulatedEntityMap populatedEntityMap,
        EntityBlueprint entityBlueprint,
        List ids,
        PhotonQuery photonQuery,
        boolean isQueryIdsOnly)
    {
        List queryResultRows;

        if(ids != null)
        {
            String selectSql = entityBlueprint.getTableBlueprint().getSelectWithQuestionSql();
            try (PhotonPreparedStatement statement = new PhotonPreparedStatement(selectSql, false, connection, photon.getOptions()))
            {
                statement.setNextArrayParameter(
                    ids,
                    entityBlueprint.getTableBlueprint().getPrimaryKeyColumn().getColumnDataType(),
                    entityBlueprint.getTableBlueprint().getPrimaryKeyColumnSerializer()
                );
                queryResultRows = statement.executeQuery(entityBlueprint.getAllColumnNamesQualified(), entityBlueprint.getAllColumnNamesQualifiedLowerCase());
            }
        }
        else if(photonQuery != null)
        {
            String selectSql;
            if(isQueryIdsOnly)
            {
                selectSql = String.format(entityBlueprint.getTableBlueprint().getSelectSql(), photonQuery.getSqlTextWithQuestionMarks());
            }
            else
            {
                selectSql = photonQuery.getSqlTextWithQuestionMarks();
            }
            try (PhotonPreparedStatement statement = new PhotonPreparedStatement(selectSql, false, connection, photon.getOptions()))
            {
                for(PhotonSqlParameter photonSqlParameter : photonQuery.getParameters())
                {
                    statement.setNextParameter(photonSqlParameter);
                }
                queryResultRows = statement.executeQuery(entityBlueprint.getAllColumnNamesQualified(), entityBlueprint.getAllColumnNamesQualifiedLowerCase());
            }
        }
        else
        {
            throw new PhotonException("Ids list and query were both null.");
        }

        queryResultRows.forEach(queryResultRow -> populatedEntityMap.createPopulatedEntity(entityBlueprint, queryResultRow));

        if(ids == null)
        {
            ids = populatedEntityMap
                .getPopulatedEntitiesForBlueprint(entityBlueprint)
                .stream()
                .map(PopulatedEntity::getPrimaryKeyValue)
                .collect(Collectors.toList());
        }

        populateFlattenedCollectionFields(populatedEntityMap, entityBlueprint, ids);

        return ids;
    }

    private void populateFlattenedCollectionFields(PopulatedEntityMap populatedEntityMap, EntityBlueprint entityBlueprint, List ids)
    {
        for(FieldBlueprint fieldBlueprint : entityBlueprint.getFlattenedCollectionFields())
        {
            FlattenedCollectionBlueprint flattenedCollectionBlueprint = fieldBlueprint.getFlattenedCollectionBlueprint();
            try (PhotonPreparedStatement statement = new PhotonPreparedStatement(flattenedCollectionBlueprint.getSelectSql(), false, connection, photon.getOptions()))
            {
                statement.setNextArrayParameter(ids, flattenedCollectionBlueprint.getColumnDataType(), null);
                List queryResultRows = statement.executeQuery(
                    flattenedCollectionBlueprint.getSelectColumnNames(),
                    flattenedCollectionBlueprint.getSelectColumnNamesLowerCase());
                populatedEntityMap.setFieldValuesOnEntityInstances(queryResultRows, fieldBlueprint, entityBlueprint);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy