diff --git a/lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb b/lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb index 5e59abb1..f814d868 100644 --- a/lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb +++ b/lib/database_consistency/checkers/column_checkers/primary_key_type_checker.rb @@ -18,6 +18,7 @@ class PrimaryKeyTypeChecker < ColumnChecker 'serial' => 'bigserial', 'integer' => 'bigint' }.freeze + PREFIXED_UUID_FUNCTION_NAME = 'prefixed_uuid_generate_v4' SQLITE_ADAPTER_NAME = 'SQLite' # We skip check when: @@ -58,11 +59,19 @@ def type_to_set # @return [Boolean] def valid? + valid_sql_type? || prefixed_uuid_default_function? + end + + def valid_sql_type? VALID_TYPES.any? do |type| column.sql_type.to_s.match?(type) end end + def prefixed_uuid_default_function? + column.default_function.to_s.match?(/\b#{PREFIXED_UUID_FUNCTION_NAME}\s*\(/) + end + # @return [Boolean] def primary_field? column.name.to_s == model.primary_key.to_s diff --git a/spec/checkers/postgresql/primary_key_type_checker_spec.rb b/spec/checkers/postgresql/primary_key_type_checker_spec.rb new file mode 100644 index 00000000..4020ee28 --- /dev/null +++ b/spec/checkers/postgresql/primary_key_type_checker_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +RSpec.describe DatabaseConsistency::Checkers::PrimaryKeyTypeChecker, :postgresql do + subject(:checker) { described_class.new(model, column) } + + let(:model) { klass } + let(:column) { klass.columns.first } + let(:klass) { define_class { |klass| klass.primary_key = :id } } + + before do + model.connection.execute(<<~SQL) + CREATE OR REPLACE FUNCTION public.prefixed_uuid_generate_v4(prefix character varying) + RETURNS character varying + AS $$ + SELECT prefix || '_00000000-0000-4000-8000-000000000000' + $$ LANGUAGE SQL; + SQL + + model.connection.execute(<<~SQL) + CREATE TABLE entities ( + id character varying DEFAULT public.prefixed_uuid_generate_v4('veh'::character varying) NOT NULL PRIMARY KEY + ) + SQL + end + + specify do + expect(checker.report).to have_attributes( + checker_name: 'PrimaryKeyTypeChecker', + table_or_model_name: klass.name, + column_or_attribute_name: 'id', + status: :ok, + error_slug: nil, + error_message: nil + ) + end +end