package org.onap.cps.spi.repository;
-import java.sql.PreparedStatement;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
-import org.hibernate.Session;
-import org.springframework.stereotype.Repository;
+import javax.persistence.Query;
+import lombok.RequiredArgsConstructor;
-@Repository
+@RequiredArgsConstructor
public class FragmentNativeRepositoryImpl implements FragmentNativeRepository {
- private static final String DROP_FRAGMENT_CONSTRAINT
- = "ALTER TABLE fragment DROP CONSTRAINT fragment_parent_id_fkey;";
- private static final String ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE
- = "ALTER TABLE fragment ADD CONSTRAINT fragment_parent_id_fkey FOREIGN KEY (parent_id) "
- + "REFERENCES fragment (id) ON DELETE CASCADE;";
- private static final String DELETE_FRAGMENT = "DELETE FROM fragment WHERE id =?;";
- private static final String ADD_ORIGINAL_FRAGMENT_CONSTRAINT
- = "ALTER TABLE fragment ADD CONSTRAINT fragment_parent_id_fkey FOREIGN KEY (parent_id) "
- + "REFERENCES fragment (id) ON DELETE NO ACTION;";
-
@PersistenceContext
- private EntityManager entityManager;
+ private final EntityManager entityManager;
@Override
- public void deleteFragmentEntity(final long fragmentEntityId) {
- final Session session = entityManager.unwrap(Session.class);
- session.doWork(connection -> {
- try (PreparedStatement preparedStatement = connection.prepareStatement(
- DROP_FRAGMENT_CONSTRAINT
- + ADD_FRAGMENT_CONSTRAINT_WITH_CASCADE
- + DELETE_FRAGMENT
- + DROP_FRAGMENT_CONSTRAINT
- + ADD_ORIGINAL_FRAGMENT_CONSTRAINT)) {
- preparedStatement.setLong(1, fragmentEntityId);
- preparedStatement.executeUpdate();
+ public void deleteByAnchorIdAndXpaths(final int anchorId, final Collection<String> xpaths) {
+ final String queryString =
+ "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath IN (:parameterPlaceholders))";
+ executeUpdateWithAnchorIdAndCollection(queryString, anchorId, xpaths);
+ }
+
+ @Override
+ public void deleteListsByAnchorIdAndXpaths(final int anchorId, final Collection<String> listXpaths) {
+ final Collection<String> listXpathPatterns =
+ listXpaths.stream().map(listXpath -> listXpath + "[%").collect(Collectors.toSet());
+ final String queryString =
+ "DELETE FROM fragment f WHERE f.anchor_id = ? AND (f.xpath LIKE ANY (array[:parameterPlaceholders]))";
+ executeUpdateWithAnchorIdAndCollection(queryString, anchorId, listXpathPatterns);
+ }
+
+ // Accept security hotspot as placeholders in SQL query are created internally, not from user input.
+ @SuppressWarnings("squid:S2077")
+ private void executeUpdateWithAnchorIdAndCollection(final String sqlTemplate, final int anchorId,
+ final Collection<String> collection) {
+ if (!collection.isEmpty()) {
+ final String parameterPlaceholders = String.join(",", Collections.nCopies(collection.size(), "?"));
+ final String queryStringWithParameterPlaceholders =
+ sqlTemplate.replaceFirst(":parameterPlaceholders\\b", parameterPlaceholders);
+
+ final Query query = entityManager.createNativeQuery(queryStringWithParameterPlaceholders);
+ query.setParameter(1, anchorId);
+ int parameterIndex = 2;
+ for (final String parameterValue : collection) {
+ query.setParameter(parameterIndex++, parameterValue);
}
- });
+ query.executeUpdate();
+ }
}
-}
+}