Skip to content

Commit

Permalink
Be a nazi with bulk alter tables.
Browse files Browse the repository at this point in the history
  • Loading branch information
oggy committed Jun 24, 2012
1 parent 3a283a0 commit 07e7608
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 42 deletions.
21 changes: 21 additions & 0 deletions lib/db_nazi.rb
Expand Up @@ -2,6 +2,7 @@ module DBNazi
autoload :AbstractAdapter, 'db_nazi/abstract_adapter'
autoload :Migration, 'db_nazi/migration'
autoload :MigrationProxy, 'db_nazi/migration_proxy'
autoload :Table, 'db_nazi/table'
autoload :TableDefinition, 'db_nazi/table_definition'
autoload :VERSION, 'db_nazi/version'

Expand Down Expand Up @@ -55,12 +56,32 @@ def reset
self.require_varchar_limits = true
self.require_index_uniqueness = true
end

def check_column(type, options)
if DBNazi.enabled?(:require_nullability) && type != :primary_key
options.key?(:null) or
raise NullabilityRequired, "[db_nazi] :null parameter required"
end
if DBNazi.enabled?(:require_varchar_limits)
# AR calls #to_sym on type, so do the same here.
type.to_sym == :string && !options.key?(:limit) and
raise VarcharLimitRequired, "[db_nazi] string column requires :limit parameter"
end
end

def check_index(options)
if DBNazi.enabled?(:require_index_uniqueness)
options.key?(:unique) or
raise IndexUniquenessRequired, "[db_nazi] :unique parameter required"
end
end
end

reset
end

ActiveRecord::ConnectionAdapters::AbstractAdapter.__send__ :include, DBNazi::AbstractAdapter
ActiveRecord::ConnectionAdapters::TableDefinition.__send__ :include, DBNazi::TableDefinition
ActiveRecord::ConnectionAdapters::Table.__send__ :include, DBNazi::Table
ActiveRecord::Migration.__send__ :include, DBNazi::Migration
ActiveRecord::MigrationProxy.__send__ :include, DBNazi::MigrationProxy
30 changes: 8 additions & 22 deletions lib/db_nazi/abstract_adapter.rb
Expand Up @@ -15,15 +15,18 @@ def new(*)

module Adapter
def add_column(table_name, column_name, type, options = {})
nazi_column_options(type, options)
DBNazi.check_column(type, options)
super
end

def add_index(table_name, column_name, options = {})
if DBNazi.enabled?(:require_index_uniqueness)
options.key?(:unique) or
raise IndexUniquenessRequired, "[db_nazi] :unique parameter required"
end
DBNazi.check_index(options)
super
end

def change_column(table_name, column_name, type, options = {})
DBNazi.check_column(type, options)
super
end

def create_table(name, *)
Expand All @@ -33,23 +36,6 @@ def create_table(name, *)
super
end
end

def change_column(table_name, column_name, type, options = {})
nazi_column_options(type, options)
super
end

def nazi_column_options(type, options)
if DBNazi.enabled?(:require_nullability)
options.key?(:null) or
raise NullabilityRequired, "[db_nazi] :null parameter required"
end
if DBNazi.enabled?(:require_varchar_limits)
# AR calls #to_sym on type, so do the same here.
type.to_sym == :string && !options.key?(:limit) and
raise VarcharLimitRequired, "[db_nazi] string column requires :limit parameter"
end
end
end
end
end
26 changes: 26 additions & 0 deletions lib/db_nazi/table.rb
@@ -0,0 +1,26 @@
module DBNazi
module Table
def self.included(base)
base.class_eval do
alias_method_chain :column, :db_nazi
alias_method_chain :index, :db_nazi
alias_method_chain :change, :db_nazi
end
end

def column_with_db_nazi(column_name, type, options = {})
DBNazi.check_column(type, options)
column_without_db_nazi(column_name, type, options)
end

def index_with_db_nazi(column_name, options = {})
DBNazi.check_index(options)
index_without_db_nazi(column_name, options)
end

def change_with_db_nazi(column_name, type, options = {})
DBNazi.check_column(type, options)
change_without_db_nazi(column_name, type, options)
end
end
end
10 changes: 1 addition & 9 deletions lib/db_nazi/table_definition.rb
Expand Up @@ -8,15 +8,7 @@ def self.included(base)
end

def column_with_db_nazi(name, type, options = {})
if DBNazi.enabled?(:require_nullability) && type != :primary_key
options.key?(:null) or
raise NullabilityRequired, "[db_nazi] :null parameter required"
end
if DBNazi.enabled?(:require_varchar_limits)
# AR calls #to_sym on type, so do the same here.
type.to_sym == :string && !options.key?(:limit) and
raise VarcharLimitRequired, "[db_nazi] string column requires :limit parameter"
end
DBNazi.check_column(type, options)
column_without_db_nazi(name, type, options)
end
end
Expand Down
189 changes: 189 additions & 0 deletions test/unit/db_nazi/test_table.rb
@@ -0,0 +1,189 @@
require_relative '../../test_helper'

describe DBNazi::TableDefinition do
use_database

before do
DBNazi.reset
end

describe "#column" do
before do
connection.create_table 'test_table'
end

describe "when nullability is required" do
use_attribute_value DBNazi, :require_nullability, true

it "raises a DBNazi::NullabilityRequired if :null is not specified" do
connection.change_table 'test_table', bulk: true do |t|
lambda do
t.column 'test_column', :boolean
end.must_raise(DBNazi::NullabilityRequired)
end
end

it "does not raise a DBNazi::NullabilityRequired if :null is true" do
connection.change_table 'test_table', bulk: true do |t|
t.column 'test_column', :boolean, null: true
end
end

it "does not raise a DBNazi::NullabilityRequired if :null is false" do
connection.change_table 'test_table', bulk: true do |t|
t.column 'test_column', :boolean, null: false, default: false
end
end
end

describe "when nullability is not required" do
use_attribute_value DBNazi, :require_nullability, false

it "does not raise a DBNazi::NullabilityRequired if :null is not specified" do
connection.change_table 'test_table', bulk: true do |t|
t.column 'test_column', :boolean
end
end
end

describe "when varchar limits are required" do
use_attribute_value DBNazi, :require_varchar_limits, true

it "raises a DBNazi::VarcharLimitRequired if :limit is not specified for a :string column" do
connection.change_table 'test_table', bulk: true do |t|
lambda do
t.column 'test_column', :string, null: true
end.must_raise(DBNazi::VarcharLimitRequired)
end
end

it "does not raise a DBNazi::VarcharLimitRequired if :limit is specified for a :string column" do
connection.change_table 'test_table', bulk: true do |t|
t.column 'test_column', :string, limit: 255, null: true
end
end
end

describe "when varchar limits are not required" do
use_attribute_value DBNazi, :require_varchar_limits, false

it "does not raise a DBNazi::VarcharLimitRequired if :limit is not specified for a :string column" do
connection.change_table 'test_table', bulk: true do |t|
t.column 'test_column', :string, null: true
end
end
end
end

describe "#index" do
before do
connection.create_table 'test_table' do |t|
t.column 'test_column', :boolean, null: true
end
end

describe "when index uniqueness is required" do
use_attribute_value DBNazi, :require_index_uniqueness, true

it "raises a DBNazi::IndexUniquenessRequired if :unique is not specified for an index" do
connection.change_table 'test_table', bulk: true do |t|
lambda do
t.index 'test_column'
end.must_raise(DBNazi::IndexUniquenessRequired)
end
end

it "does not raise a DBNazi::IndexUniquenessRequired if :unique is true for an index" do
connection.change_table 'test_table', bulk: true do |t|
t.index 'test_column', unique: true
end
end

it "does not raise a DBNazi::IndexUniquenessRequired if :unique is false for an index" do
connection.change_table 'test_table', bulk: true do |t|
t.index 'test_column', unique: false
end
end
end

describe "when index uniqueness is not required" do
use_attribute_value DBNazi, :require_index_uniqueness, false

it "does not raise a DBNazi::IndexUniquenessRequired if :unique is not specified for an index" do
connection.change_table 'test_table', bulk: true do |t|
t.index 'test_column'
end
end
end
end

describe "#change" do
before do
connection.create_table 'test_table' do |t|
t.column 'test_column', :boolean, null: true
end
end

describe "when nullability is required" do
use_attribute_value DBNazi, :require_nullability, true

it "raises a DBNazi::NullabilityRequired if :null is not specified" do
connection.change_table 'test_table', bulk: true do |t|
lambda do
t.change 'test_column', :boolean
end.must_raise(DBNazi::NullabilityRequired)
end
end

it "does not raise a DBNazi::NullabilityRequired if :null is true" do
connection.change_table 'test_table', bulk: true do |t|
t.change 'test_column', :boolean, null: true
end
end

it "does not raise a DBNazi::NullabilityRequired if :null is false" do
connection.change_table 'test_table', bulk: true do |t|
t.change 'test_column', :boolean, null: false, default: false
end
end
end

describe "when nullability is not required" do
use_attribute_value DBNazi, :require_nullability, false

it "does not raise a DBNazi::NullabilityRequired if :null is not specified" do
connection.change_table 'test_table', bulk: true do |t|
t.change 'test_column', :boolean
end
end
end

describe "when varchar limits are required" do
use_attribute_value DBNazi, :require_varchar_limits, true

it "raises a DBNazi::VarcharLimitRequired if :limit is not specified for a :string column" do
connection.change_table 'test_table', bulk: true do |t|
lambda do
t.change 'test_column', :string, null: true
end.must_raise(DBNazi::VarcharLimitRequired)
end
end

it "does not raise a DBNazi::VarcharLimitRequired if :limit is specified for a :string column" do
connection.change_table 'test_table', bulk: true do |t|
t.change 'test_column', :string, limit: 255, null: true
end
end
end

describe "when varchar limits are not required" do
use_attribute_value DBNazi, :require_varchar_limits, false

it "does not raise a DBNazi::VarcharLimitRequired if :limit is not specified for a :string column" do
connection.change_table 'test_table', bulk: true do |t|
t.change 'test_column', :string, null: true
end
end
end
end
end
20 changes: 9 additions & 11 deletions test/unit/db_nazi/test_table_definition.rb
Expand Up @@ -7,44 +7,42 @@
DBNazi.reset
end

describe "nullability" do
describe "when it is required" do
describe "#column" do
describe "when nullability is required" do
use_attribute_value DBNazi, :require_nullability, true

it "raises a DBNazi::NullabilityRequired if :null is not specified when adding a column" do
it "raises a DBNazi::NullabilityRequired if :null is not specified" do
connection.create_table 'test_table' do |t|
lambda do
t.column 'test_column', :boolean
end.must_raise(DBNazi::NullabilityRequired)
end
end

it "does not raise a DBNazi::NullabilityRequired if :null is true when adding a column" do
it "does not raise a DBNazi::NullabilityRequired if :null is true" do
connection.create_table 'test_table' do |t|
t.column 'test_column', :boolean, null: true
end
end

it "does not raise a DBNazi::NullabilityRequired if :null is false when adding a column" do
it "does not raise a DBNazi::NullabilityRequired if :null is false" do
connection.create_table 'test_table' do |t|
t.column 'test_column', :boolean, null: false, default: false
end
end
end

describe "when it is not required" do
describe "when nullability is not required" do
use_attribute_value DBNazi, :require_nullability, false

it "does not raise a DBNazi::NullabilityRequired if :null is not specified when adding a column" do
it "does not raise a DBNazi::NullabilityRequired if :null is not specified" do
connection.create_table 'test_table' do |t|
t.column 'test_column', :boolean
end
end
end
end

describe "varchar limits" do
describe "when they are required" do
describe "when varchar limits are required" do
use_attribute_value DBNazi, :require_varchar_limits, true

it "raises a DBNazi::VarcharLimitRequired if :limit is not specified for a :string column" do
Expand All @@ -62,7 +60,7 @@
end
end

describe "when they are not required" do
describe "when varchar limits are not required" do
use_attribute_value DBNazi, :require_varchar_limits, false

it "does not raise a DBNazi::VarcharLimitRequired if :limit is not specified for a :string column" do
Expand Down

0 comments on commit 07e7608

Please sign in to comment.