Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/rein.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
require 'rein/schema'
require 'rein/type/enum'
require 'rein/view'
require 'rein/schema_dumper'

module ActiveRecord
class Migration # :nodoc:
Expand All @@ -33,4 +34,8 @@ class Migration # :nodoc:
include Rein::Type::Enum
include Rein::View
end

class SchemaDumper
prepend Rein::SchemaDumper
end
end
58 changes: 58 additions & 0 deletions lib/rein/schema_dumper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module Rein
# @api private
module SchemaDumper
def tables(stream)
super
check_constraints(stream)
end

def check_constraints(stream)
puts constraints.to_a

stream.puts if constraints.any?

constraints.each do |constraint|
column_name = constraint['column_name']
check_clause = constraint['check_clause']

case check_clause
when /#{column_name}\s+(>=|>|=|!=|<|<=)\s+(\d+)/
add_numericality_constraint_command(stream, constraint, $1, $2)
end
end
end

private

def constraints
@constraints ||= @connection.execute <<-SQL
select *
from information_schema.check_constraints as c, information_schema.constraint_column_usage as u
where c.constraint_name = u.constraint_name
and c.constraint_schema = 'public'
and u.constraint_schema = 'public'
SQL
end

def add_numericality_constraint_command(stream, constraint, operator, value)
table_name = constraint['table_name']
column_name = constraint['column_name']

definition = definition_from_numerical_operator(operator)
stream.puts <<-RUBY
add_numericality_constraint "#{table_name}", "#{column_name}", #{definition}: #{value}
RUBY
end

def definition_from_numerical_operator(operator)
case operator
when '>=' then 'greater_than_or_equal_to'
when '>' then 'greater_than'
when '<=' then 'less_than_or_equal_to'
when '<' then 'less_than'
when '=' then 'equal_to'
when '!=' then 'not_equal_to'
end
end
end
end
4 changes: 4 additions & 0 deletions spec/integration/reversible_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def down(*args)
Migrator.migrate
end

after(:all) do
Migrator.migrate
end

it 'reverses check constraints' do
expect(TableConstraint.where(constraint_name: 'no_r_titles')).to exist
Migrator.down(2)
Expand Down
12 changes: 12 additions & 0 deletions spec/integration/schema_dumper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'spec_helper'

RSpec.describe Rein::SchemaDumper do
it 'dumps constraints from the database' do
stream = StringIO.new

ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)

output = stream.string
expect(output).to include 'add_numericality_constraint "books", "published_month", greater_than_or_equal_to: 1'
end
end