Skip to content

Commit

Permalink
Implicit Order Column value checker
Browse files Browse the repository at this point in the history
  • Loading branch information
developie0610 committed Jul 20, 2023
1 parent 33c2fce commit 64187ab
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 2 deletions.
2 changes: 2 additions & 0 deletions lib/database_consistency.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
require 'database_consistency/writers/simple/enum_values_inconsistent_with_inclusion'
require 'database_consistency/writers/simple/redundant_case_insensitive_option'
require 'database_consistency/writers/simple/three_state_boolean'
require 'database_consistency/writers/simple/implicit_order_column_missing'
require 'database_consistency/writers/simple_writer'

require 'database_consistency/writers/autofix/helpers/migration'
Expand Down Expand Up @@ -73,6 +74,7 @@
require 'database_consistency/checkers/column_checkers/primary_key_type_checker'
require 'database_consistency/checkers/column_checkers/enum_value_checker'
require 'database_consistency/checkers/column_checkers/three_state_boolean_checker'
require 'database_consistency/checkers/column_checkers/implicit_ordering_checker.rb'

require 'database_consistency/checkers/validator_checkers/validator_checker'
require 'database_consistency/checkers/validator_checkers/missing_unique_index_checker'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

module DatabaseConsistency
module Checkers
# This class checks that primary column type is "uuid" and the model class defines `self.implicit_order_column` method
class ImplicitOrderingChecker < ColumnChecker
Report = ReportBuilder.define(
DatabaseConsistency::Report,
:model_name,
:primary_fk_name
)

private

TARGET_COLUMN_TYPE = 'uuid'

# We skip check when:
# - adapter is not PostgreSQL
# - column is not a primary key
# - column type is not "uuid"
def preconditions
Helper.postgresql? && primary_field? && column.sql_type.to_s.match(TARGET_COLUMN_TYPE)
end

# Table of possible statuses
# | defined `self.implicit_order_column` | status |
# | ----------------------------------- | ------ |
# | yes | ok |
# | no | fail |
def check
if implicit_order_column_defined?
report_template(:ok)
else
report_template(:fail, error_slug: :implicit_order_column_missing)
end
end

def report_template(status, error_slug: nil)
Report.new(
status: status,
error_slug: error_slug,
error_message: nil,
model_name: model.name,
primary_fk_name: column.name,
**report_attributes
)
end

# @return [Boolean]
def primary_field?
column.name.to_s == model.primary_key.to_s
end

# @return [Boolean]
def implicit_order_column_defined?
model.implicit_order_column.present?
end
end
end
end
3 changes: 2 additions & 1 deletion lib/database_consistency/processors/columns_processor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class ColumnsProcessor < BaseProcessor
Checkers::LengthConstraintChecker,
Checkers::PrimaryKeyTypeChecker,
Checkers::EnumValueChecker,
Checkers::ThreeStateBooleanChecker
Checkers::ThreeStateBooleanChecker,
Checkers::ImplicitOrderingChecker
].freeze

private
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module DatabaseConsistency
module Writers
module Simple
class ImplicitOrderColumnMissing < Base # :nodoc:
private

def template
'implicit_order_column is recommended when using uuid column type for primary key'
end

def unique_attributes
{
table_or_model_name: report.table_or_model_name,
column_or_attribute_name: report.column_or_attribute_name
}
end
end
end
end
end
3 changes: 2 additions & 1 deletion lib/database_consistency/writers/simple_writer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class SimpleWriter < BaseWriter
enum_values_inconsistent_with_ar_enum: Simple::EnumValuesInconsistentWithArEnum,
enum_values_inconsistent_with_inclusion: Simple::EnumValuesInconsistentWithInclusion,
redundant_case_insensitive_option: Simple::RedundantCaseInsensitiveOption,
three_state_boolean: Simple::ThreeStateBoolean
three_state_boolean: Simple::ThreeStateBoolean,
implicit_order_column_missing: Simple::ImplicitOrderColumnMissing
}.freeze

def write
Expand Down
63 changes: 63 additions & 0 deletions spec/checkers/implicit_ordering_checker_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

RSpec.describe DatabaseConsistency::Checkers::ImplicitOrderingChecker, :postgresql do
subject(:checker) { described_class.new(model, column) }

let(:klass) { define_class { |klass| klass.primary_key = :id } }
let(:model) { klass }
let(:column) { klass.columns.first }

context 'when primary key type is uuid and model defines self.implicit_order_column' do
before do
define_database do
create_table :entities, id: :uuid
end

klass.class_eval do
self.implicit_order_column = :created_at
end
end

specify do
expect(checker.report).to have_attributes(
checker_name: 'ImplicitOrderingChecker',
model_name: klass.name,
primary_fk_name: 'id',
status: :ok,
error_slug: nil,
error_message: nil
)
end
end

context 'when primary key type is uuid and model does not define self.implicit_order_column' do
before do
define_database do
create_table :entities, id: :uuid
end
end

specify do
expect(checker.report).to have_attributes(
checker_name: 'ImplicitOrderingChecker',
model_name: klass.name,
primary_fk_name: 'id',
status: :fail,
error_slug: :implicit_order_column_missing,
error_message: nil
)
end
end

context 'when primary key type is not uuid' do
before do
define_database do
create_table :entities, id: :bigint
end
end

specify do
expect(checker.report).to be_nil
end
end
end

0 comments on commit 64187ab

Please sign in to comment.