/*\r
* ============LICENSE_START=======================================================\r
- * Copyright (C) 2021-2022 Nordix Foundation.\r
+ * Copyright (C) 2021-2023 Nordix Foundation.\r
* Modifications Copyright (C) 2020-2021 Bell Canada.\r
* Modifications Copyright (C) 2020-2021 Pantheon.tech.\r
+ * Modifications Copyright (C) 2023 TechMahindra Ltd.\r
* ================================================================================\r
* Licensed under the Apache License, Version 2.0 (the "License");\r
* you may not use this file except in compliance with the License.\r
import java.util.Collection;\r
import java.util.List;\r
import java.util.Optional;\r
-import javax.validation.constraints.NotNull;\r
-import org.checkerframework.checker.nullness.qual.NonNull;\r
import org.onap.cps.spi.entities.AnchorEntity;\r
-import org.onap.cps.spi.entities.DataspaceEntity;\r
import org.onap.cps.spi.entities.FragmentEntity;\r
import org.onap.cps.spi.entities.FragmentExtract;\r
import org.onap.cps.spi.exceptions.DataNodeNotFoundException;\r
import org.springframework.stereotype.Repository;\r
\r
@Repository\r
-public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, FragmentRepositoryCpsPathQuery,\r
- FragmentRepositoryMultiPathQuery {\r
-\r
- Optional<FragmentEntity> findByDataspaceAndAnchorAndXpath(@NonNull DataspaceEntity dataspaceEntity,\r
- @NonNull AnchorEntity anchorEntity,\r
- @NonNull String xpath);\r
-\r
- default FragmentEntity getByDataspaceAndAnchorAndXpath(@NonNull DataspaceEntity dataspaceEntity,\r
- @NonNull AnchorEntity anchorEntity,\r
- @NonNull String xpath) {\r
- return findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, xpath)\r
- .orElseThrow(() -> new DataNodeNotFoundException(dataspaceEntity.getName(), anchorEntity.getName(), xpath));\r
+public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, FragmentRepositoryCpsPathQuery {\r
+\r
+ Optional<FragmentEntity> findByAnchorAndXpath(AnchorEntity anchorEntity, String xpath);\r
+\r
+ default FragmentEntity getByAnchorAndXpath(final AnchorEntity anchorEntity, final String xpath) {\r
+ return findByAnchorAndXpath(anchorEntity, xpath).orElseThrow(() ->\r
+ new DataNodeNotFoundException(anchorEntity.getDataspace().getName(), anchorEntity.getName(), xpath));\r
}\r
\r
- @Query(\r
- value = "SELECT * FROM FRAGMENT WHERE anchor_id = :anchor AND dataspace_id = :dataspace AND parent_id is NULL",\r
- nativeQuery = true)\r
- List<FragmentEntity> findRootsByDataspaceAndAnchor(@Param("dataspace") int dataspaceId,\r
- @Param("anchor") int anchorId);\r
+ boolean existsByAnchorId(int anchorId);\r
\r
- @Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId,"\r
- + " CAST(attributes AS TEXT) AS attributes"\r
- + " FROM FRAGMENT WHERE anchor_id = :anchorId",\r
- nativeQuery = true)\r
- List<FragmentExtract> findRootsByAnchorId(@Param("anchorId") int anchorId);\r
-\r
- /**\r
- * find top level fragment by anchor.\r
- *\r
- * @param dataspaceEntity dataspace entity\r
- * @param anchorEntity anchor entity\r
- * @return FragmentEntity fragment entity\r
- */\r
- default List<FragmentExtract> getTopLevelFragments(DataspaceEntity dataspaceEntity,\r
- AnchorEntity anchorEntity) {\r
- final List<FragmentExtract> fragmentExtracts = findRootsByAnchorId(anchorEntity.getId());\r
- if (fragmentExtracts.isEmpty()) {\r
- throw new DataNodeNotFoundException(dataspaceEntity.getName(), anchorEntity.getName());\r
- }\r
- return fragmentExtracts;\r
+ @Query("SELECT f FROM FragmentEntity f WHERE anchor = :anchor")\r
+ List<FragmentExtract> findAllExtractsByAnchor(@Param("anchor") AnchorEntity anchorEntity);\r
+\r
+ @Query(value = "SELECT * FROM fragment WHERE xpath = ANY (:xpaths)", nativeQuery = true)\r
+ List<FragmentEntity> findAllByXpathIn(@Param("xpaths") String[] xpath);\r
+\r
+ default List<FragmentEntity> findAllByXpathIn(final Collection<String> xpaths) {\r
+ return findAllByXpathIn(xpaths.toArray(new String[0]));\r
}\r
\r
@Modifying\r
- @Query("DELETE FROM FragmentEntity fe WHERE fe.anchor IN (:anchors)")\r
- void deleteByAnchorIn(@NotNull @Param("anchors") Collection<AnchorEntity> anchorEntities);\r
+ @Query(value = "DELETE FROM fragment WHERE anchor_id = ANY (:anchorIds)", nativeQuery = true)\r
+ void deleteByAnchorIdIn(@Param("anchorIds") int[] anchorIds);\r
\r
- @Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId,"\r
- + " CAST(attributes AS TEXT) AS attributes"\r
- + " FROM FRAGMENT WHERE anchor_id = :anchorId"\r
- + " AND ( xpath = :parentXpath OR xpath LIKE CONCAT(:parentXpath,'/%') )",\r
- nativeQuery = true)\r
- List<FragmentExtract> findByAnchorIdAndParentXpath(@Param("anchorId") int anchorId,\r
- @Param("parentXpath") String parentXpath);\r
+ default void deleteByAnchorIn(final Collection<AnchorEntity> anchorEntities) {\r
+ deleteByAnchorIdIn(anchorEntities.stream().map(AnchorEntity::getId).mapToInt(id -> id).toArray());\r
+ }\r
+\r
+ @Modifying\r
+ @Query(value = "DELETE FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)", nativeQuery = true)\r
+ void deleteByAnchorIdAndXpaths(@Param("anchorId") int anchorId, @Param("xpaths") String[] xpaths);\r
+\r
+ default void deleteByAnchorIdAndXpaths(final int anchorId, final Collection<String> xpaths) {\r
+ deleteByAnchorIdAndXpaths(anchorId, xpaths.toArray(new String[0]));\r
+ }\r
+\r
+ @Modifying\r
+ @Query(value = "DELETE FROM fragment f WHERE anchor_id = :anchorId AND xpath LIKE ANY (:xpathPatterns)",\r
+ nativeQuery = true)\r
+ void deleteByAnchorIdAndXpathLikeAny(@Param("anchorId") int anchorId,\r
+ @Param("xpathPatterns") String[] xpathPatterns);\r
+\r
+ default void deleteListsByAnchorIdAndXpaths(int anchorId, Collection<String> xpaths) {\r
+ final String[] listXpathPatterns = xpaths.stream().map(xpath -> xpath + "[%").toArray(String[]::new);\r
+ deleteByAnchorIdAndXpathLikeAny(anchorId, listXpathPatterns);\r
+ }\r
+\r
+ @Query("SELECT f FROM FragmentEntity f WHERE anchor = :anchor"\r
+ + " AND (xpath = :parentXpath OR xpath LIKE CONCAT(:parentXpath,'/%'))")\r
+ List<FragmentExtract> findByAnchorAndParentXpath(@Param("anchor") AnchorEntity anchorEntity,\r
+ @Param("parentXpath") String parentXpath);\r
\r
@Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId,"\r
+ " CAST(attributes AS TEXT) AS attributes"\r
nativeQuery = true)\r
List<FragmentExtract> quickFindWithDescendants(@Param("anchorId") int anchorId,\r
@Param("xpathRegex") String xpathRegex);\r
+\r
+ @Query(value = "SELECT xpath FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)",\r
+ nativeQuery = true)\r
+ List<String> findAllXpathByAnchorIdAndXpathIn(@Param("anchorId") int anchorId,\r
+ @Param("xpaths") String[] xpaths);\r
+\r
+ default List<String> findAllXpathByAnchorAndXpathIn(final AnchorEntity anchorEntity,\r
+ final Collection<String> xpaths) {\r
+ return findAllXpathByAnchorIdAndXpathIn(anchorEntity.getId(), xpaths.toArray(new String[0]));\r
+ }\r
+\r
+ boolean existsByAnchorAndXpathStartsWith(AnchorEntity anchorEntity, String xpath);\r
+\r
+ @Query("SELECT xpath FROM FragmentEntity WHERE anchor = :anchor AND parentId IS NULL")\r
+ List<String> findAllXpathByAnchorAndParentIdIsNull(@Param("anchor") AnchorEntity anchorEntity);\r
+\r
+ @Query(value\r
+ = "WITH RECURSIVE parent_search AS ("\r
+ + " SELECT id, 0 AS depth "\r
+ + " FROM fragment "\r
+ + " WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths) "\r
+ + " UNION "\r
+ + " SELECT c.id, depth + 1 "\r
+ + " FROM fragment c INNER JOIN parent_search p ON c.parent_id = p.id"\r
+ + " WHERE depth <= (SELECT CASE WHEN :maxDepth = -1 THEN " + Integer.MAX_VALUE + " ELSE :maxDepth END) "\r
+ + ") "\r
+ + "SELECT f.id, anchor_id AS anchorId, xpath, f.parent_id AS parentId, CAST(attributes AS TEXT) AS attributes "\r
+ + "FROM fragment f INNER JOIN parent_search p ON f.id = p.id",\r
+ nativeQuery = true\r
+ )\r
+ List<FragmentExtract> findExtractsWithDescendants(@Param("anchorId") int anchorId,\r
+ @Param("xpaths") String[] xpaths,\r
+ @Param("maxDepth") int maxDepth);\r
+\r
+ default List<FragmentExtract> findExtractsWithDescendants(final int anchorId, final Collection<String> xpaths,\r
+ final int maxDepth) {\r
+ return findExtractsWithDescendants(anchorId, xpaths.toArray(new String[0]), maxDepth);\r
+ }\r
+\r
+ @Query(value = "SELECT id, anchor_id AS anchorId, xpath, parent_id AS parentId,"\r
+ + " CAST(attributes AS TEXT) AS attributes"\r
+ + " FROM FRAGMENT WHERE xpath ~ :xpathRegex",\r
+ nativeQuery = true)\r
+ List<FragmentExtract> quickFindWithDescendantsAcrossAnchors(@Param("xpathRegex") String xpathRegex);\r
}\r