openSUSE/open-build-service

View on GitHub
src/api/app/models/package_issue.rb

Summary

Maintainability
A
0 mins
Test Coverage
B
84%
class PackageIssue < ApplicationRecord
  belongs_to :package
  belongs_to :issue

  after_save :populate_to_sphinx

  scope :open_issues_of_owner, ->(owner_id) { joins(:issue).where(issues: { state: 'OPEN', owner_id: owner_id }) }
  scope :with_patchinfo, lambda {
    joins('LEFT JOIN package_kinds ON package_kinds.package_id = package_issues.package_id').where('package_kinds.kind = "patchinfo"')
  }

  def self.sync_relations(package, issues)
    retries = 10
    begin
      PackageIssue.transaction do
        allissues = []
        issues.map { |h| allissues += h.last }

        # drop not anymore existing relations
        PackageIssue.where('package_id = ? AND NOT issue_id IN (?)', package, allissues).lock(true).delete_all

        # create missing in an efficient way
        sql = ApplicationRecord.connection
        (allissues - package.issues.to_ary).each do |i|
          sql.execute("INSERT INTO `package_issues` (`package_id`, `issue_id`) VALUES (#{package.id},#{i.id})")
        end

        # set change value for all
        issues.each do |pair|
          # rubocop:disable Rails/SkipsModelValidations
          PackageIssue.where(package: package, issue: pair.last).lock(true).update_all(change: pair.first)
          # rubocop:enable Rails/SkipsModelValidations
        end
      end
    rescue ActiveRecord::StatementInvalid, Mysql2::Error
      retries -= 1
      retry if retries.positive?
    end
  end

  private

  def populate_to_sphinx
    PopulateToSphinxJob.perform_later(id: id, model_name: :package_issue,
                                      reference: :package, path: [:package])
    PopulateToSphinxJob.perform_later(id: id, model_name: :package_issue,
                                      reference: :project, path: %i[package project])
  end
end

# == Schema Information
#
# Table name: package_issues
#
#  id         :integer          not null, primary key
#  change     :string
#  issue_id   :integer          not null, indexed, indexed => [package_id]
#  package_id :integer          not null, indexed => [issue_id]
#
# Indexes
#
#  index_package_issues_on_issue_id                 (issue_id)
#  index_package_issues_on_package_id_and_issue_id  (package_id,issue_id)
#
# Foreign Keys
#
#  package_issues_ibfk_1  (package_id => packages.id)
#  package_issues_ibfk_2  (issue_id => issues.id)
#