diff options
author | danielhanrahan <daniel.hanrahan@est.tech> | 2024-09-02 12:04:51 +0100 |
---|---|---|
committer | danielhanrahan <daniel.hanrahan@est.tech> | 2024-09-06 15:04:31 +0100 |
commit | 8b3258f21f9957f356bed6cb222361ec09cefd04 (patch) | |
tree | 988c5db69bbdb615057a25f22e8f1a40a19a24d4 | |
parent | 406a7428b835078b3be04c3b84d586f6fac6c014 (diff) |
Refactor FragmentQueryBuilder
This is a refactoring of FragmentQueryBuilder, there are
no functional changes. This refactoring is needed before
main patch of CPS-2365.
Issue-ID: CPS-2365
Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech>
Change-Id: I648616159719e084ba0e7cb4b09649cd17560cab
-rw-r--r-- | cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java | 168 |
1 files changed, 89 insertions, 79 deletions
diff --git a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java index 8171bbe621..eb61d56632 100644 --- a/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java +++ b/cps-ri/src/main/java/org/onap/cps/spi/repository/FragmentQueryBuilder.java @@ -24,14 +24,12 @@ package org.onap.cps.spi.repository; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.persistence.Query; -import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.onap.cps.cpspath.parser.CpsPathPrefixType; import org.onap.cps.cpspath.parser.CpsPathQuery; import org.onap.cps.spi.PaginationOption; @@ -43,10 +41,8 @@ import org.onap.cps.spi.utils.EscapeUtils; import org.springframework.stereotype.Component; @RequiredArgsConstructor -@Slf4j @Component public class FragmentQueryBuilder { - private static final AnchorEntity ACROSS_ALL_ANCHORS = null; @PersistenceContext private EntityManager entityManager; @@ -59,8 +55,14 @@ public class FragmentQueryBuilder { * @return a executable query object */ public Query getQueryForAnchorAndCpsPath(final AnchorEntity anchorEntity, final CpsPathQuery cpsPathQuery) { - return getQueryForDataspaceOrAnchorAndCpsPath(anchorEntity.getDataspace(), - anchorEntity, cpsPathQuery, Collections.emptyList()); + final StringBuilder sqlStringBuilder = new StringBuilder(); + final Map<String, Object> queryParameters = new HashMap<>(); + + sqlStringBuilder.append("SELECT fragment.* FROM fragment"); + addWhereClauseForAnchor(anchorEntity, sqlStringBuilder, queryParameters); + addNodeSearchConditions(cpsPathQuery, sqlStringBuilder, queryParameters, false); + + return getQuery(sqlStringBuilder.toString(), queryParameters, FragmentEntity.class); } /** @@ -73,8 +75,18 @@ public class FragmentQueryBuilder { public Query getQueryForDataspaceAndCpsPath(final DataspaceEntity dataspaceEntity, final CpsPathQuery cpsPathQuery, final List<Long> anchorIdsForPagination) { - return getQueryForDataspaceOrAnchorAndCpsPath(dataspaceEntity, ACROSS_ALL_ANCHORS, - cpsPathQuery, anchorIdsForPagination); + final StringBuilder sqlStringBuilder = new StringBuilder(); + final Map<String, Object> queryParameters = new HashMap<>(); + + sqlStringBuilder.append("SELECT fragment.* FROM fragment"); + if (anchorIdsForPagination.isEmpty()) { + addWhereClauseForDataspace(dataspaceEntity, sqlStringBuilder, queryParameters); + } else { + addWhereClauseForAnchorIds(anchorIdsForPagination, sqlStringBuilder, queryParameters); + } + addNodeSearchConditions(cpsPathQuery, sqlStringBuilder, queryParameters, true); + + return getQuery(sqlStringBuilder.toString(), queryParameters, FragmentEntity.class); } /** @@ -89,52 +101,52 @@ public class FragmentQueryBuilder { final PaginationOption paginationOption) { final StringBuilder sqlStringBuilder = new StringBuilder(); final Map<String, Object> queryParameters = new HashMap<>(); - sqlStringBuilder.append("SELECT distinct(fragment.anchor_id) FROM fragment " - + "JOIN anchor ON anchor.id = fragment.anchor_id WHERE dataspace_id = :dataspaceId"); - queryParameters.put("dataspaceId", dataspaceEntity.getId()); - addAbsoluteParentXpathSearchCondition(cpsPathQuery, sqlStringBuilder, queryParameters, ACROSS_ALL_ANCHORS); - addXpathSearchCondition(cpsPathQuery, sqlStringBuilder, queryParameters); - addLeafConditions(cpsPathQuery, sqlStringBuilder); - addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); - addContainsFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); - if (PaginationOption.NO_PAGINATION != paginationOption) { - sqlStringBuilder.append(" ORDER BY fragment.anchor_id"); - addPaginationCondition(sqlStringBuilder, queryParameters, paginationOption); - } - final Query query = entityManager.createNativeQuery(sqlStringBuilder.toString()); + sqlStringBuilder.append("SELECT distinct(fragment.anchor_id) FROM fragment"); + addWhereClauseForDataspace(dataspaceEntity, sqlStringBuilder, queryParameters); + addNodeSearchConditions(cpsPathQuery, sqlStringBuilder, queryParameters, true); + sqlStringBuilder.append(" ORDER BY fragment.anchor_id"); + addPaginationCondition(sqlStringBuilder, queryParameters, paginationOption); + + return getQuery(sqlStringBuilder.toString(), queryParameters, Long.class); + } + + private Query getQuery(final String sql, final Map<String, Object> queryParameters, final Class<?> returnType) { + final Query query = entityManager.createNativeQuery(sql, returnType); setQueryParameters(query, queryParameters); return query; } - private Query getQueryForDataspaceOrAnchorAndCpsPath(final DataspaceEntity dataspaceEntity, - final AnchorEntity anchorEntity, - final CpsPathQuery cpsPathQuery, - final List<Long> anchorIdsForPagination) { - final StringBuilder sqlStringBuilder = new StringBuilder(); - final Map<String, Object> queryParameters = new HashMap<>(); + private static void addWhereClauseForAnchor(final AnchorEntity anchorEntity, + final StringBuilder sqlStringBuilder, + final Map<String, Object> queryParameters) { + sqlStringBuilder.append(" WHERE anchor_id = :anchorId"); + queryParameters.put("anchorId", anchorEntity.getId()); + } - if (anchorEntity == ACROSS_ALL_ANCHORS) { - sqlStringBuilder.append("SELECT fragment.* FROM fragment JOIN anchor ON anchor.id = fragment.anchor_id" - + " WHERE dataspace_id = :dataspaceId"); - queryParameters.put("dataspaceId", dataspaceEntity.getId()); - if (!anchorIdsForPagination.isEmpty()) { - sqlStringBuilder.append(" AND anchor_id IN (:anchorIdsForPagination)"); - queryParameters.put("anchorIdsForPagination", anchorIdsForPagination); - } - } else { - sqlStringBuilder.append("SELECT * FROM fragment WHERE anchor_id = :anchorId"); - queryParameters.put("anchorId", anchorEntity.getId()); - } - addAbsoluteParentXpathSearchCondition(cpsPathQuery, sqlStringBuilder, queryParameters, anchorEntity); + private static void addWhereClauseForAnchorIds(final List<Long> anchorIdsForPagination, + final StringBuilder sqlStringBuilder, + final Map<String, Object> queryParameters) { + sqlStringBuilder.append(" WHERE anchor_id IN (:anchorIdsForPagination)"); + queryParameters.put("anchorIdsForPagination", anchorIdsForPagination); + } + + private static void addWhereClauseForDataspace(final DataspaceEntity dataspaceEntity, + final StringBuilder sqlStringBuilder, + final Map<String, Object> queryParameters) { + sqlStringBuilder.append(" JOIN anchor ON anchor.id = fragment.anchor_id WHERE dataspace_id = :dataspaceId"); + queryParameters.put("dataspaceId", dataspaceEntity.getId()); + } + + private static void addNodeSearchConditions(final CpsPathQuery cpsPathQuery, + final StringBuilder sqlStringBuilder, + final Map<String, Object> queryParameters, + final boolean acrossAnchors) { + addAbsoluteParentXpathSearchCondition(cpsPathQuery, sqlStringBuilder, queryParameters, acrossAnchors); addXpathSearchCondition(cpsPathQuery, sqlStringBuilder, queryParameters); addLeafConditions(cpsPathQuery, sqlStringBuilder); addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); addContainsFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters); - - final Query query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class); - setQueryParameters(query, queryParameters); - return query; } private static void addXpathSearchCondition(final CpsPathQuery cpsPathQuery, @@ -152,12 +164,12 @@ public class FragmentQueryBuilder { private static void addAbsoluteParentXpathSearchCondition(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder, final Map<String, Object> queryParameters, - final AnchorEntity anchorEntity) { + final boolean acrossAnchors) { if (CpsPathPrefixType.ABSOLUTE.equals(cpsPathQuery.getCpsPathPrefixType())) { if (cpsPathQuery.getNormalizedParentPath().isEmpty()) { sqlStringBuilder.append(" AND parent_id IS NULL"); } else { - if (anchorEntity == ACROSS_ALL_ANCHORS) { + if (acrossAnchors) { sqlStringBuilder.append(" AND parent_id IN (SELECT id FROM fragment WHERE xpath = :parentXpath)"); } else { sqlStringBuilder.append(" AND parent_id = (SELECT id FROM fragment WHERE xpath = :parentXpath" @@ -171,10 +183,12 @@ public class FragmentQueryBuilder { private static void addPaginationCondition(final StringBuilder sqlStringBuilder, final Map<String, Object> queryParameters, final PaginationOption paginationOption) { - final Integer offset = (paginationOption.getPageIndex() - 1) * paginationOption.getPageSize(); - sqlStringBuilder.append(" LIMIT :pageSize OFFSET :offset"); - queryParameters.put("pageSize", paginationOption.getPageSize()); - queryParameters.put("offset", offset); + if (PaginationOption.NO_PAGINATION != paginationOption) { + final Integer offset = (paginationOption.getPageIndex() - 1) * paginationOption.getPageSize(); + sqlStringBuilder.append(" LIMIT :pageSize OFFSET :offset"); + queryParameters.put("pageSize", paginationOption.getPageSize()); + queryParameters.put("offset", offset); + } } private static Integer getTextValueAsInt(final CpsPathQuery cpsPathQuery) { @@ -185,38 +199,34 @@ public class FragmentQueryBuilder { } } - private void addLeafConditions(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder) { + private static void addLeafConditions(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder) { if (cpsPathQuery.hasLeafConditions()) { - queryLeafConditions(cpsPathQuery, sqlStringBuilder); - } - } - - private void queryLeafConditions(final CpsPathQuery cpsPathQuery, final StringBuilder sqlStringBuilder) { - sqlStringBuilder.append(" AND ("); - final Queue<String> booleanOperatorsQueue = new LinkedList<>(cpsPathQuery.getBooleanOperators()); - cpsPathQuery.getLeafConditions().forEach(leafCondition -> { - if (leafCondition.value() instanceof Integer) { - sqlStringBuilder.append("(attributes ->> '").append(leafCondition.name()).append("')\\:\\:int"); - sqlStringBuilder.append(leafCondition.operator()); - sqlStringBuilder.append(leafCondition.value()); - } else { - if ("=".equals(leafCondition.operator())) { - final String leafValueAsText = leafCondition.value().toString(); - sqlStringBuilder.append("attributes ->> '").append(leafCondition.name()).append("'"); - sqlStringBuilder.append(" = '"); - sqlStringBuilder.append(EscapeUtils.escapeForSqlStringLiteral(leafValueAsText)); - sqlStringBuilder.append("'"); + sqlStringBuilder.append(" AND ("); + final Queue<String> booleanOperatorsQueue = new LinkedList<>(cpsPathQuery.getBooleanOperators()); + cpsPathQuery.getLeafConditions().forEach(leafCondition -> { + if (leafCondition.value() instanceof Integer) { + sqlStringBuilder.append("(attributes ->> '").append(leafCondition.name()).append("')\\:\\:int"); + sqlStringBuilder.append(leafCondition.operator()); + sqlStringBuilder.append(leafCondition.value()); } else { - throw new CpsPathException(" can use only " + leafCondition.operator() + " with integer "); + if ("=".equals(leafCondition.operator())) { + final String leafValueAsText = leafCondition.value().toString(); + sqlStringBuilder.append("attributes ->> '").append(leafCondition.name()).append("'"); + sqlStringBuilder.append(" = '"); + sqlStringBuilder.append(EscapeUtils.escapeForSqlStringLiteral(leafValueAsText)); + sqlStringBuilder.append("'"); + } else { + throw new CpsPathException(" can use only " + leafCondition.operator() + " with integer "); + } } - } - if (!booleanOperatorsQueue.isEmpty()) { - sqlStringBuilder.append(" "); - sqlStringBuilder.append(booleanOperatorsQueue.poll()); - sqlStringBuilder.append(" "); - } - }); - sqlStringBuilder.append(")"); + if (!booleanOperatorsQueue.isEmpty()) { + sqlStringBuilder.append(" "); + sqlStringBuilder.append(booleanOperatorsQueue.poll()); + sqlStringBuilder.append(" "); + } + }); + sqlStringBuilder.append(")"); + } } private static void addTextFunctionCondition(final CpsPathQuery cpsPathQuery, |