Switch to UNION ALL for active reminders scope on repository cells [SCI-11134] (#7938)

This commit is contained in:
Alex Kriuchykhin 2024-10-08 09:57:34 +02:00 committed by GitHub
parent 66c2fa639e
commit c57c99f36a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 39 additions and 20 deletions

View file

@ -46,17 +46,14 @@ class RepositoryCell < ApplicationRecord
after_touch :update_repository_row_last_modified_by
scope :with_active_reminder, lambda { |user|
joins(
'LEFT OUTER JOIN repository_columns repository_reminder_columns ON ' \
'repository_reminder_columns.id = repository_cells.repository_column_id'
).joins( # datetime reminders
'LEFT OUTER JOIN "repository_date_time_values" ON ' \
'"repository_date_time_values"."id" = "repository_cells"."value_id" AND ' \
'"repository_cells"."value_type" = \'RepositoryDateTimeValueBase\' AND ' \
'"repository_reminder_columns"."metadata" ->> \'reminder_value\' <> \'\' AND ' \
'(repository_date_time_values.data - NOW()) <= (repository_reminder_columns.metadata ->> \'reminder_value\')::int * ' \
'(repository_reminder_columns.metadata ->> \'reminder_unit\')::int * interval \'1 sec\''
).joins( # stock reminders
from(
"((#{with_active_stock_reminder(user).to_sql}) UNION ALL " \
"(#{with_active_datetime_reminder(user).to_sql})) AS repository_cells"
)
}
scope :with_active_stock_reminder, lambda { |user|
joins( # stock reminders
'LEFT OUTER JOIN "repository_stock_values" ON ' \
'"repository_cells"."value_type" = \'RepositoryStockValue\' AND ' \
'"repository_stock_values"."id" = "repository_cells"."value_id" AND ' \
@ -67,8 +64,28 @@ class RepositoryCell < ApplicationRecord
'"repository_cells"."id" = "hidden_repository_cell_reminders"."repository_cell_id" AND ' \
'"hidden_repository_cell_reminders"."user_id" = ' + user.id.to_s
).where(
'hidden_repository_cell_reminders.id IS NULL AND ' \
'(repository_date_time_values.id IS NOT NULL OR repository_stock_values.id IS NOT NULL)'
'hidden_repository_cell_reminders.id IS NULL AND repository_stock_values.id IS NOT NULL'
)
}
scope :with_active_datetime_reminder, lambda { |user|
joins(
'INNER JOIN repository_columns repository_reminder_columns ON ' \
'repository_reminder_columns.id = repository_cells.repository_column_id'
).joins( # datetime reminders
'LEFT OUTER JOIN "repository_date_time_values" ON ' \
'"repository_date_time_values"."id" = "repository_cells"."value_id" AND ' \
'"repository_cells"."value_type" = \'RepositoryDateTimeValueBase\' ' \
'AND repository_reminder_columns.metadata ->> \'reminder_value\' <> \'\' AND ' \
'(repository_date_time_values.data - NOW()) <= ' \
'(repository_reminder_columns.metadata ->> \'reminder_value\')::int * ' \
'(repository_reminder_columns.metadata ->> \'reminder_unit\')::int * interval \'1 sec\''
).joins(
'LEFT OUTER JOIN "hidden_repository_cell_reminders" ON ' \
'"repository_cells"."id" = "hidden_repository_cell_reminders"."repository_cell_id" AND ' \
'"hidden_repository_cell_reminders"."user_id" = ' + user.id.to_s
).where(
'hidden_repository_cell_reminders.id IS NULL AND repository_date_time_values.id IS NOT NULL'
)
}

View file

@ -116,8 +116,8 @@ class RepositoryRow < ApplicationRecord
scope :active, -> { where(archived: false) }
scope :archived, -> { where(archived: true) }
scope :with_active_reminders, lambda { |user|
left_outer_joins_active_reminders(user).where.not(repository_cells_with_active_reminders: { id: nil })
scope :with_active_reminders, lambda { |repository, user|
left_outer_joins_active_reminders(repository, user).where.not(repository_cells_with_active_reminders: { id: nil })
}
def code
@ -170,9 +170,11 @@ class RepositoryRow < ApplicationRecord
.update_all(created_by_id: new_owner.id)
end
def self.left_outer_joins_active_reminders(user)
def self.left_outer_joins_active_reminders(repository, user)
repository_cells = RepositoryCell.joins("INNER JOIN repository_columns ON repository_columns.id = repository_cells.repository_column_id AND " \
"repository_columns.repository_id = #{repository.id}")
joins(
"LEFT OUTER JOIN (#{RepositoryCell.with_active_reminder(user).select(:id, :repository_row_id).to_sql}) " \
"LEFT OUTER JOIN (#{repository_cells.with_active_reminder(user).select(:id, :repository_row_id).to_sql}) " \
"AS repository_cells_with_active_reminders " \
"ON repository_cells_with_active_reminders.repository_row_id = repository_rows.id"
)

View file

@ -47,7 +47,7 @@ class RepositoryDatatableService
repository_rows = fetch_rows(search_value)
# filter only rows with reminders if filter param is present
repository_rows = repository_rows.with_active_reminders(@user) if @params[:only_reminders]
repository_rows = repository_rows.with_active_reminders(@repository, @user) if @params[:only_reminders]
# Aliased my_module_repository_rows join for consistent assigned counts
repository_rows =
@ -85,7 +85,7 @@ class RepositoryDatatableService
# don't load reminders for archived repositories or snapshots
repository_rows.select('FALSE AS has_active_stock_reminders, FALSE AS has_active_datetime_reminders')
else
repository_rows.left_outer_joins_active_reminders(@user)
repository_rows.left_outer_joins_active_reminders(@repository, @user)
.select('COUNT(repository_cells_with_active_reminders.id) > 0 AS has_active_reminders')
end
end

View file

@ -37,7 +37,7 @@
</button>
</span>
<% end %>
<% if @repository.has_reminders? && @repository.repository_rows.with_active_reminders(current_user).any? %>
<% if @repository.has_reminders? && @repository.repository_rows.with_active_reminders(@repository, current_user).any? %>
<button type="button" data-toggle="tooltip" data-placement="bottom" title="<%= t("repositories.hide_reminders") %>"
class="btn btn-light auto-shrink-button"
id="hideRepositoryReminders"