Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public interface DashboardRepository extends ReportPortalRepository<Dashboard, L
* Finds dashboard by 'id' and 'project id'
*
* @param id {@link Dashboard#id}
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose
* dashboard will be extracted
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose dashboard will be
* extracted
* @return {@link Dashboard} wrapped in the {@link Optional}
*/
Optional<Dashboard> findByIdAndProjectId(Long id, Long projectId);
Expand All @@ -46,8 +46,8 @@ public interface DashboardRepository extends ReportPortalRepository<Dashboard, L
*
* @param name {@link Dashboard#name}
* @param owner {@link Dashboard#owner}
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which
* dashboard existence will be checked
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which dashboard existence
* will be checked
* @return if exists 'true' else 'false'
*/
boolean existsByNameAndOwnerAndProjectId(String name, String owner, Long projectId);
Expand All @@ -63,13 +63,12 @@ public interface DashboardRepository extends ReportPortalRepository<Dashboard, L


/**
* Toggles the lock flag for the specified dashboard and all related widgets and filters.
* Toggles the lock flag for the specified dashboard and all related widgets.
*
* <p>Performs three native update statements:
* <p>Performs native update statements:
* <ul>
* <li>Updates the dashboard owned_entity row.</li>
* <li>Updates owned_entity rows for widgets linked to the dashboard.</li>
* <li>Updates owned_entity rows for filters linked to those widgets.</li>
* </ul>
*
* @param dashboardId id of the dashboard to toggle lock for
Expand All @@ -79,8 +78,7 @@ public interface DashboardRepository extends ReportPortalRepository<Dashboard, L
WITH widget_ids AS (SELECT widget_id FROM dashboard_widget WHERE dashboard_id = :dashboardId)
UPDATE owned_entity SET locked = true
WHERE id = :dashboardId
OR id IN (SELECT widget_id FROM widget_ids)
OR id IN (SELECT filter_id FROM widget_filter WHERE widget_id IN (SELECT widget_id FROM widget_ids));
OR id IN (SELECT widget_id FROM widget_ids);
""", nativeQuery = true)
void lockDashboard(@Param("dashboardId") Long dashboardId);

Expand All @@ -90,43 +88,8 @@ OR id IN (SELECT widget_id FROM widget_ids)
WITH widget_ids AS (SELECT widget_id FROM dashboard_widget WHERE dashboard_id = :dashboardId)
UPDATE owned_entity SET locked = false
WHERE id = :dashboardId
OR id IN (SELECT widget_id FROM widget_ids)
OR (
id IN (SELECT filter_id FROM widget_filter WHERE widget_id IN (SELECT widget_id FROM widget_ids))
AND id NOT IN (
SELECT DISTINCT wf.filter_id
FROM widget_filter wf
JOIN dashboard_widget dw ON wf.widget_id = dw.widget_id
JOIN owned_entity oe ON dw.dashboard_id = oe.id
WHERE oe.locked = true AND oe.id != :dashboardId
)
);
OR id IN (SELECT widget_id FROM widget_ids);
""", nativeQuery = true)
void unlockDashboard(@Param("dashboardId") Long dashboardId);

/**
* Unlocks all dashboard filters that are related to the specified dashboard
* and not related to any other locked dashboard.
*
* @param dashboardId id of the dashboard to unlock filters for
*/
@Modifying
@Query(value = """
UPDATE owned_entity SET locked = false
WHERE id IN (
SELECT DISTINCT wf.filter_id
FROM widget_filter wf
JOIN dashboard_widget dw ON wf.widget_id = dw.widget_id
WHERE dw.dashboard_id = :dashboardId
)
AND id NOT IN (
SELECT DISTINCT wf.filter_id
FROM widget_filter wf
JOIN dashboard_widget dw ON wf.widget_id = dw.widget_id
JOIN owned_entity oe ON dw.dashboard_id = oe.id
WHERE oe.locked = true AND oe.id != :dashboardId
);
""", nativeQuery = true)
void unlockDashboardFilters(@Param("dashboardId") Long dashboardId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

/**
* @author Pavel Bortnik
Expand All @@ -33,20 +31,23 @@ public interface UserFilterRepository extends ReportPortalRepository<UserFilter,
* Finds filter by 'id' and 'project id'
*
* @param id {@link UserFilter#id}
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose filter will be extracted
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose filter
* will be extracted
* @return {@link UserFilter} wrapped in the {@link Optional}
*/
Optional<UserFilter> findByIdAndProjectId(Long id, Long projectId);

/**
* @param ids {@link Iterable} of the filter Ids
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose filters will be extracted
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose
* filters will be extracted
* @return The {@link List} of the {@link UserFilter}
*/
List<UserFilter> findAllByIdInAndProjectId(Collection<Long> ids, Long projectId);

/**
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose filters will be extracted
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose
* filters will be extracted
* @return The {@link List} of the {@link UserFilter}
*/
List<UserFilter> findAllByProjectId(Long projectId);
Expand All @@ -56,8 +57,8 @@ public interface UserFilterRepository extends ReportPortalRepository<UserFilter,
*
* @param name {@link UserFilter#name}
* @param owner {@link UserFilter#owner}
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which filter existence will
* be checked
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which
* filter existence will be checked
* @return if exists 'true' else 'false'
*/
boolean existsByNameAndOwnerAndProjectId(String name, String owner, Long projectId);
Expand All @@ -66,31 +67,10 @@ public interface UserFilterRepository extends ReportPortalRepository<UserFilter,
* Checks the existence of the {@link UserFilter} with specified name on a project
*
* @param name {@link UserFilter#name}
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which filter existence will
* be checked
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which
* filter existence will be checked
* @return if exists 'true' else 'false'
*/
boolean existsByNameAndProjectId(String name, Long projectId);

/**
* Finds locked dashboards that use the specified filter. Returns dashboard names.
*
* @param filterId The filter ID
* @param projectId The project ID to filter dashboards
* @return List of dashboard names
*/
@Query(value = """
SELECT d.name
FROM dashboard d
INNER JOIN owned_entity oe ON d.id = oe.id
WHERE oe.locked = true
AND oe.project_id = :projectId
AND d.id IN (
SELECT dw.dashboard_id
FROM dashboard_widget dw
INNER JOIN widget_filter wf ON dw.widget_id = wf.widget_id
WHERE wf.filter_id = :filterId
)
""", nativeQuery = true)
List<String> findLockedDashboardsByFilterId(@Param("filterId") Long filterId, @Param("projectId") Long projectId);
}
56 changes: 4 additions & 52 deletions src/main/java/com/epam/ta/reportportal/dao/WidgetRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.epam.ta.reportportal.entity.widget.Widget;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

Expand All @@ -33,15 +32,13 @@ public interface WidgetRepository extends ReportPortalRepository<Widget, Long>,
* Finds widget by 'id' and 'project id'
*
* @param id {@link Widget#id}
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose widget
* will be extracted
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose widget will be extracted
* @return {@link Widget} wrapped in the {@link Optional}
*/
Optional<Widget> findByIdAndProjectId(Long id, Long projectId);

/**
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose
* widgets will be extracted
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} whose widgets will be extracted
* @return The {@link List} of the {@link Widget}
*/
List<Widget> findAllByProjectId(Long projectId);
Expand All @@ -51,8 +48,8 @@ public interface WidgetRepository extends ReportPortalRepository<Widget, Long>,
*
* @param name {@link Widget#name}
* @param owner {@link Widget#owner}
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which
* widget existence will be checked
* @param projectId Id of the {@link com.epam.ta.reportportal.entity.project.Project} on which widget existence will
* be checked
* @return if exists 'true' else 'false'
*/
boolean existsByNameAndOwnerAndProjectId(String name, String owner, Long projectId);
Expand All @@ -74,49 +71,4 @@ List<Widget> findAllByProjectIdAndWidgetTypeInAndContentFieldsContains(
+ " WHERE se.project_id = :projectId AND w.widget_type IN :widgetTypes AND cf.field LIKE :contentFieldPart || '%'", nativeQuery = true)
List<Widget> findAllByProjectIdAndWidgetTypeInAndContentFieldContaining(@Param("projectId") Long projectId,
@Param("widgetTypes") List<String> widgetTypes, @Param("contentFieldPart") String contentFieldPart);

/**
* Unlocks all widget filters that are related to the specified widget
* and not related to any other locked dashboard.
*
* @param widgetId id of the widget to unlock filters for
*/
@Modifying
@Query(value = """
UPDATE owned_entity SET locked = false
WHERE id IN (
SELECT DISTINCT wf.filter_id
FROM widget_filter wf
WHERE wf.widget_id = :widgetId
)
AND id NOT IN (
SELECT DISTINCT wf.filter_id
FROM widget_filter wf
JOIN dashboard_widget dw ON wf.widget_id = dw.widget_id
JOIN owned_entity oe ON dw.dashboard_id = oe.id
WHERE oe.locked = true
);
""", nativeQuery = true)
void unlockWidgetFilters(@Param("widgetId") Long widgetId);


/**
* Locks all widget filters that are related to the specified widget.
*
* <p>This operation sets the `locked` flag to true on entries in the
* `owned_entity` table for every filter referenced by the given widget
* (via the `widget_filter` join table).</p>
*
* @param widgetId id of the widget to lock filters for
*/
@Modifying
@Query(value = """
UPDATE owned_entity SET locked = true
WHERE id IN (
SELECT DISTINCT wf.filter_id
FROM widget_filter wf
WHERE wf.widget_id = :widgetId
);
""", nativeQuery = true)
void lockWidgetFilters(@Param("widgetId") Long widgetId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,17 @@ void toggleDashboardLock() {
}

@Test
void unlockDashboardFilters() {
void lockDashboardShouldNotLockFilters() {
dashboardRepository.lockDashboard(13L);
dashboardRepository.lockDashboard(18L);
entityManager.flush();
entityManager.clear();

assertTrue(filterRepository.findById(2L).get().getLocked());
assertTrue(filterRepository.findById(3L).get().getLocked());

dashboardRepository.unlockDashboardFilters(13L);
entityManager.clear();
// Dashboard should be locked
Dashboard dashboard = dashboardRepository.findById(13L).get();
assertTrue(dashboard.getLocked());

// Filters should NOT be locked
assertFalse(filterRepository.findById(2L).get().getLocked());
assertTrue(filterRepository.findById(3L).get().getLocked());
}

}