diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 09:08:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 09:08:42 +0000 |
commit | b76ae638462ab0f673e5915986070518dd3f9ad3 (patch) | |
tree | bdab0533383b52873be0ec0eb4d3c66598ff8b91 /app/models/analytics/cycle_analytics | |
parent | 434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff) | |
download | gitlab-ce-b76ae638462ab0f673e5915986070518dd3f9ad3.tar.gz |
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'app/models/analytics/cycle_analytics')
-rw-r--r-- | app/models/analytics/cycle_analytics/stage_event_hash.rb | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/app/models/analytics/cycle_analytics/stage_event_hash.rb b/app/models/analytics/cycle_analytics/stage_event_hash.rb new file mode 100644 index 00000000000..0e1e9b3ef67 --- /dev/null +++ b/app/models/analytics/cycle_analytics/stage_event_hash.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Analytics + module CycleAnalytics + class StageEventHash < ApplicationRecord + has_many :cycle_analytics_project_stages, class_name: 'Analytics::CycleAnalytics::ProjectStage', inverse_of: :stage_event_hash + + validates :hash_sha256, presence: true + + # Creates or queries the id of the corresponding stage event hash code + def self.record_id_by_hash_sha256(hash) + casted_hash_code = Arel::Nodes.build_quoted(hash, Analytics::CycleAnalytics::StageEventHash.arel_table[:hash_sha256]).to_sql + + # Atomic, safe insert without retrying + query = <<~SQL + WITH insert_cte AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} ( + INSERT INTO #{quoted_table_name} (hash_sha256) VALUES (#{casted_hash_code}) ON CONFLICT DO NOTHING RETURNING ID + ) + SELECT ids.id FROM ( + (SELECT id FROM #{quoted_table_name} WHERE hash_sha256=#{casted_hash_code} LIMIT 1) + UNION ALL + (SELECT id FROM insert_cte LIMIT 1) + ) AS ids LIMIT 1 + SQL + + connection.execute(query).first['id'] + end + + def self.cleanup_if_unused(id) + unused_hashes_for(id) + .where(id: id) + .delete_all + end + + def self.unused_hashes_for(id) + exists_query = Analytics::CycleAnalytics::ProjectStage.where(stage_event_hash_id: id).select('1').limit(1) + where.not('EXISTS (?)', exists_query) + end + end + end +end +Analytics::CycleAnalytics::StageEventHash.prepend_mod_with('Analytics::CycleAnalytics::StageEventHash') |