diff options
author | Nick Thomas <nick@gitlab.com> | 2019-01-23 19:27:09 +0000 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2019-01-23 19:27:09 +0000 |
commit | f40e769211ea708ede1c581d999e5b0d92586c0b (patch) | |
tree | 04c092f53a7dc1f9a5a7e1bcc4aec93e2a98bdef /config | |
parent | c051fe6ebda0811f5eab067855c984c8745cae96 (diff) | |
parent | 26978cb270feef10756d34a646c0676083737ab8 (diff) | |
download | gitlab-ce-f40e769211ea708ede1c581d999e5b0d92586c0b.tar.gz |
Merge branch '52674-api-v4-projects-project_id-jobs-endpoint-hits-statement-timeout' into 'master'
[API] Omit `X-Total` and `X-Total-Pages` headers when items count is more than 10,000
Closes #42194 and #52674
See merge request gitlab-org/gitlab-ce!23931
Diffstat (limited to 'config')
-rw-r--r-- | config/initializers/kaminari_active_record_relation_methods_with_limit.rb | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/config/initializers/kaminari_active_record_relation_methods_with_limit.rb b/config/initializers/kaminari_active_record_relation_methods_with_limit.rb new file mode 100644 index 00000000000..cc20b83b234 --- /dev/null +++ b/config/initializers/kaminari_active_record_relation_methods_with_limit.rb @@ -0,0 +1,41 @@ +module Kaminari + # Active Record specific page scope methods implementations + module ActiveRecordRelationMethodsWithLimit + MAX_COUNT_LIMIT = 10_000 + + # This is a modified version of + # https://github.com/kaminari/kaminari/blob/c5186f5d9b7f23299d115408e62047447fd3189d/kaminari-activerecord/lib/kaminari/activerecord/active_record_relation_methods.rb#L17-L41 + # that limit the COUNT query to 10,000 to avoid query timeouts. + # rubocop: disable Gitlab/ModuleWithInstanceVariables + def total_count_with_limit(column_name = :all, _options = nil) #:nodoc: + return @total_count if defined?(@total_count) && @total_count + + # There are some cases that total count can be deduced from loaded records + if loaded? + # Total count has to be 0 if loaded records are 0 + return @total_count = 0 if (current_page == 1) && @records.empty? + # Total count is calculable at the last page + return @total_count = (current_page - 1) * limit_value + @records.length if @records.any? && (@records.length < limit_value) + end + + # #count overrides the #select which could include generated columns referenced in #order, so skip #order here, where it's irrelevant to the result anyway + c = except(:offset, :limit, :order) + # Remove includes only if they are irrelevant + c = c.except(:includes) unless references_eager_loaded_tables? + # .group returns an OrderedHash that responds to #count + # The following line was modified from `c = c.count(:all)` + c = c.limit(MAX_COUNT_LIMIT + 1).count(column_name) + @total_count = + if c.is_a?(Hash) || c.is_a?(ActiveSupport::OrderedHash) + c.count + elsif c.respond_to? :count + c.count(column_name) + else + c + end + end + # rubocop: enable Gitlab/ModuleWithInstanceVariables + + Kaminari::ActiveRecordRelationMethods.prepend(self) + end +end |