Migrate CPS to Spring-boot 3.0
[cps.git] / cps-ri / src / main / java / org / onap / cps / spi / repository / FragmentRepository.java
index a40168a..1a31d2b 100755 (executable)
@@ -1,7 +1,9 @@
-/*-\r
+/*\r
  * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2020 Nordix Foundation. All rights reserved.\r
- *  Modifications Copyright (C) 2020 Bell Canada. All rights reserved.\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
@@ -24,12 +26,11 @@ package org.onap.cps.spi.repository;
 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.exceptions.DataNodeNotFoundException;\r
+import org.onap.cps.spi.utils.EscapeUtils;\r
 import org.springframework.data.jpa.repository.JpaRepository;\r
 import org.springframework.data.jpa.repository.Modifying;\r
 import org.springframework.data.jpa.repository.Query;\r
@@ -37,27 +38,103 @@ import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;\r
 \r
 @Repository\r
-public interface FragmentRepository extends JpaRepository<FragmentEntity, Long> {\r
+public interface FragmentRepository extends JpaRepository<FragmentEntity, Long>, FragmentRepositoryCpsPathQuery,\r
+        FragmentPrefetchRepository {\r
 \r
-    Optional<FragmentEntity> findByDataspaceAndAnchorAndXpath(@NonNull DataspaceEntity dataspaceEntity,\r
-        @NonNull AnchorEntity anchorEntity, @NonNull String xpath);\r
+    Optional<FragmentEntity> findByAnchorAndXpath(AnchorEntity anchorEntity, String xpath);\r
 \r
-    default FragmentEntity getByDataspaceAndAnchorAndXpath(@NonNull DataspaceEntity dataspaceEntity,\r
-        @NonNull AnchorEntity anchorEntity, @NonNull String xpath) {\r
-        return findByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, xpath)\r
-            .orElseThrow(() -> new DataNodeNotFoundException(dataspaceEntity.getName(), anchorEntity.getName(), xpath));\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(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)",\r
+            nativeQuery = true)\r
+    List<FragmentEntity> findByAnchorIdAndXpathIn(@Param("anchorId") long anchorId,\r
+                                                  @Param("xpaths") String[] xpaths);\r
+\r
+    default List<FragmentEntity> findByAnchorAndXpathIn(final AnchorEntity anchorEntity,\r
+                                                        final Collection<String> xpaths) {\r
+        return findByAnchorIdAndXpathIn(anchorEntity.getId(), xpaths.toArray(new String[0]));\r
+    }\r
+\r
+    @Query(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId \n"\r
+            + "AND xpath LIKE :escapedXpath||'[@%]' AND xpath NOT LIKE :escapedXpath||'[@%]/%[@%]'",\r
+            nativeQuery = true)\r
+    List<FragmentEntity> findListByAnchorIdAndEscapedXpath(@Param("anchorId") long anchorId,\r
+                                                           @Param("escapedXpath") String escapedXpath);\r
+\r
+    default List<FragmentEntity> findListByAnchorAndXpath(final AnchorEntity anchorEntity, final String xpath) {\r
+        final String escapedXpath = EscapeUtils.escapeForSqlLike(xpath);\r
+        return findListByAnchorIdAndEscapedXpath(anchorEntity.getId(), escapedXpath);\r
+    }\r
+\r
+    @Query(value = "SELECT fragment.* FROM fragment JOIN anchor ON anchor.id = fragment.anchor_id "\r
+        + "WHERE dataspace_id = :dataspaceId AND xpath = ANY (:xpaths)", nativeQuery = true)\r
+    List<FragmentEntity> findByDataspaceIdAndXpathIn(@Param("dataspaceId") int dataspaceId,\r
+                                                     @Param("xpaths") String[] xpaths);\r
+\r
+    default List<FragmentEntity> findByDataspaceAndXpathIn(final DataspaceEntity dataspaceEntity,\r
+                                                           final Collection<String> xpaths) {\r
+        return findByDataspaceIdAndXpathIn(dataspaceEntity.getId(), xpaths.toArray(new String[0]));\r
+    }\r
+\r
+    @Query(value = "SELECT * FROM fragment WHERE anchor_id IN (:anchorIds)"\r
+            + " AND xpath = ANY (:xpaths)", nativeQuery = true)\r
+    List<FragmentEntity> findByAnchorIdsAndXpathIn(@Param("anchorIds") Long[] anchorIds,\r
+                                                   @Param("xpaths") String[] xpaths);\r
+\r
+    @Query(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId LIMIT 1", nativeQuery = true)\r
+    Optional<FragmentEntity> findOneByAnchorId(@Param("anchorId") long anchorId);\r
+\r
+    @Modifying\r
+    @Query(value = "DELETE FROM fragment WHERE anchor_id = ANY (:anchorIds)", nativeQuery = true)\r
+    void deleteByAnchorIdIn(@Param("anchorIds") long[] anchorIds);\r
+\r
+    default void deleteByAnchorIn(final Collection<AnchorEntity> anchorEntities) {\r
+        deleteByAnchorIdIn(anchorEntities.stream().map(AnchorEntity::getId).mapToLong(id -> id).toArray());\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
-\r
-    @Query(value =\r
-        "SELECT * FROM FRAGMENT WHERE (anchor_id = :anchor) AND (xpath = (:xpath) OR xpath LIKE "\r
-            + "CONCAT(:xpath,'\\[@%]')) AND attributes @> jsonb_build_object(:leafName , :leafValue)",\r
-                nativeQuery = true)\r
-    // Above query will match an xpath with or without the index for a list [@key=value]\r
-    // and match anchor id, leaf name and leaf value\r
-    List<FragmentEntity> getByAnchorAndXpathAndLeafAttributes(@Param("anchor") int anchorId, @Param("xpath")\r
-        String xpathPrefix, @Param("leafName") String leafName, @Param("leafValue") Object leafValue);\r
-}
\ No newline at end of file
+    @Query(value = "DELETE FROM fragment WHERE anchor_id = :anchorId AND xpath = ANY (:xpaths)", nativeQuery = true)\r
+    void deleteByAnchorIdAndXpaths(@Param("anchorId") long anchorId, @Param("xpaths") String[] xpaths);\r
+\r
+    default void deleteByAnchorIdAndXpaths(final long 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") long anchorId,\r
+                                         @Param("xpathPatterns") String[] xpathPatterns);\r
+\r
+    default void deleteListsByAnchorIdAndXpaths(long anchorId, Collection<String> xpaths) {\r
+        deleteByAnchorIdAndXpathLikeAny(anchorId,\r
+                xpaths.stream().map(xpath -> EscapeUtils.escapeForSqlLike(xpath) + "[@%").toArray(String[]::new));\r
+    }\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") long 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
+    @Query(value = "SELECT EXISTS(SELECT 1 FROM fragment WHERE anchor_id = :anchorId"\r
+            + " AND xpath LIKE :xpathPattern LIMIT 1)", nativeQuery = true)\r
+    boolean existsByAnchorIdAndParentXpathAndXpathLike(@Param("anchorId") long anchorId,\r
+                                                       @Param("xpathPattern") String xpathPattern);\r
+\r
+    default boolean existsByAnchorAndXpathStartsWith(final AnchorEntity anchorEntity, final String xpath) {\r
+        return existsByAnchorIdAndParentXpathAndXpathLike(anchorEntity.getId(),\r
+                EscapeUtils.escapeForSqlLike(xpath) + "%");\r
+    }\r
+\r
+    @Query(value = "SELECT * FROM fragment WHERE anchor_id = :anchorId AND parent_id IS NULL", nativeQuery = true)\r
+    List<FragmentEntity> findRootsByAnchorId(@Param("anchorId") long anchorId);\r
+\r
+}\r