Welcome to mirror list, hosted at ThFree Co, Russian Federation.

stage_event_hash.rb « cycle_analytics « analytics « models « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7dcabd01ebfbcf75453c4bb84e63bf129d2a95bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# frozen_string_literal: true

module Analytics
  module CycleAnalytics
    class StageEventHash < ApplicationRecord
      has_many :cycle_analytics_stages, class_name: 'Analytics::CycleAnalytics::Stage', 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 MATERIALIZED (
          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)
        stage_exists_query = ::Analytics::CycleAnalytics::Stage.where(stage_event_hash_id: id).select('1').limit(1)

        where.not('EXISTS (?)', stage_exists_query)
      end
    end
  end
end