Enum 생성

새로운 enum을 만들 때, 데이터베이스 유형 SMALLINT를 사용해아 합니다. SMALLINT 유형의 크기는 2바이트이며, enum에 충분합니다. 이는 데이터베이스에서 공간을 절약하는 데 도움이 될 것입니다.

이 유형을 사용하려면 열을 만드는 마이그레이션에 limit: 2를 추가하십시오.

예시:

def change
  add_column :ci_job_artifacts, :file_format, :integer, limit: 2
end

FOSS에 모든 키/값 쌍을 정의해야 함

요약: 모델이 FOSS의 일부인 경우 모든 enum은 FOSS에 정의되어야 합니다.

class Model < ApplicationRecord
  enum platform: {
    aws: 0,
    gcp: 1      # EE-only
  }
end

enum에 새로운 키/값 쌍을 추가하고 EE 전용인 경우, 다음과 같이 enum을 구성할 유혹을 느낄 수 있습니다.

# 'Pipeline' 모델에서 'failure_reason' enum 정의:
class Pipeline < ApplicationRecord
  enum failure_reason: Enums::Pipeline.failure_reasons
end
# FOSS 및 EE에서 사용되는 키/값 쌍 정의:
module Enums
  module Pipeline
    def self.failure_reasons
      { unknown_failure: 0, config_error: 1 }
    end
  end
end

Enums::Pipeline.prepend_mod_with('Enums::Pipeline')
# EE 전용으로 사용되는 키/값 쌍 정의:
module EE
  module Enums
    module Pipeline
      override :failure_reasons
      def failure_reasons
        super.merge(job_activity_limit_exceeded: 2)
      end
    end
  end
end

이것은 여러 문제점이 있지만 현재로서는 작동합니다:

  • 누군가가 FOSS에서 정의된 값을 conflicted하는 EE의 키/값 쌍을 정의할 수 있습니다. 예: EE::Enums::Pipeline에서 job_activity_limit_exceeded: 1을 정의합니다.
  • 이런 일이 일어날 경우, 기능이 완전히 다르게 작동합니다. 예: ‘failure_reason’이 ‘config_error’인지 ‘job_activity_limit_exceeded’인지 파악할 수 없습니다.
  • 이런 일이 발생하면 데이터 무결성을 수정하는 데이터베이스 마이그레이션을 배포해야 합니다. 원래 값을 복구할 수 없는 경우 불가능할 수 있습니다.

또한, EE 모듈의 값에 오프셋을 설정하여이 문제를 해결할 수 있을 것입니다. 예를 들어, 이 예제에서는 1000을 오프셋으로 설정합니다:

module EE
  module Enums
    module Pipeline
      override :failure_reasons
      def failure_reasons
        super.merge(job_activity_limit_exceeded: 1_000, size_limit_exceeded: 1_001)
      end
    end
  end
end

이것은 문제를 해결하는 것처럼 보이지만, 이 접근 방식에는 몇 가지 단점이 있습니다:

  • 기능이 FOSS로 이동하거나 그 반대로 이동할 수 있습니다. 따라서 오프셋은 앞으로 FOSS 및 EE 사이에 혼합 될 수 있습니다. 예: ‘job_activity_limit_exceeded’를 FOSS로 이동할 때 ‘{ unknown_failure: 0, config_error: 1, job_activity_limit_exceeded: 1_000 }’과 같이 식별됩니다.
  • enum의 정수 열은 일반적으로 as SMALLINT로 생성됩니다. 따라서 오프셋이 2바이트 정수의 최대값을 초과하지 않도록 주의해야 합니다.

결론적으로, 모든 키/값 쌍을 FOSS에 정의해야 합니다. 예를 들어, 위의 경우 다음 코드를 작성할 수 있습니다:

class Pipeline < ApplicationRecord
  enum failure_reason: {
    unknown_failure: 0,
    config_error: 1,
    job_activity_limit_exceeded: 2
  }
end

갭에 새로운 값 추가

일부 EE 및 FOSS enum을 병합 한 후에는 두 그룹의 값 사이에 갭이 생길 수 있습니다:

module Enums
  module Ci
    module CommitStatus
      def self.failure_reasons
        {
          # ...
          data_integrity_failure: 12,
          forward_deployment_failure: 13,
          insufficient_bridge_permissions: 1_001,
          downstream_bridge_project_not_found: 1_002,
          # ...
        }
      end
    end
  end
end

새로운 값은 갭을 먼저 채워야 합니다. 위의 예제에서 1_003 대신 14를 추가하십시오:

{
  # ...
  data_integrity_failure: 12,
  forward_deployment_failure: 13,
  a_new_value: 14,
  insufficient_bridge_permissions: 1_001,
  downstream_bridge_project_not_found: 1_002,
  # ...
}