aspgems-foreign_key_migrations 2.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG +109 -0
  3. data/Gemfile +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +91 -0
  6. data/Rakefile +69 -0
  7. data/foreign_key_migrations.gemspec +28 -0
  8. data/init.rb +1 -0
  9. data/install.rb +1 -0
  10. data/lib/foreign_key_migrations.rb +48 -0
  11. data/lib/foreign_key_migrations/active_record/base.rb +36 -0
  12. data/lib/foreign_key_migrations/active_record/connection_adapters/schema_statements.rb +23 -0
  13. data/lib/foreign_key_migrations/active_record/connection_adapters/table_definition.rb +50 -0
  14. data/lib/foreign_key_migrations/active_record/migration.rb +62 -0
  15. data/lib/foreign_key_migrations/version.rb +3 -0
  16. data/lib/generators/foreign_key_migrations/migration_generator.rb +38 -0
  17. data/lib/generators/foreign_key_migrations/templates/migration.rb +10 -0
  18. data/spec/aaa_create_tables_spec.rb +9 -0
  19. data/spec/connections/mysql/connection.rb +16 -0
  20. data/spec/connections/mysql2/connection.rb +16 -0
  21. data/spec/connections/postgresql/connection.rb +13 -0
  22. data/spec/migration_spec.rb +257 -0
  23. data/spec/models/comment.rb +3 -0
  24. data/spec/models/post.rb +3 -0
  25. data/spec/models/user.rb +2 -0
  26. data/spec/references_spec.rb +48 -0
  27. data/spec/schema/schema.rb +24 -0
  28. data/spec/schema_dumper_spec.rb +32 -0
  29. data/spec/schema_spec.rb +65 -0
  30. data/spec/spec_helper.rb +15 -0
  31. data/spec/support/helpers.rb +8 -0
  32. data/spec/support/matchers/foreign_key_migrations_matchers.rb +2 -0
  33. data/spec/support/matchers/have_index.rb +52 -0
  34. data/spec/support/matchers/reference.rb +66 -0
  35. metadata +144 -0
@@ -0,0 +1,3 @@
1
+ class Comment < ActiveRecord::Base
2
+ belongs_to :post
3
+ end
@@ -0,0 +1,3 @@
1
+ class Post < ActiveRecord::Base
2
+ has_many :comments
3
+ end
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
+
4
+ describe 'references method' do
5
+
6
+ before(:all) do
7
+ @target = ActiveRecord::Base
8
+ @table_name = 'comments'
9
+ @column_name = 'post_id'
10
+ @destination_table = 'posts'
11
+ @destinantion_column = :id
12
+ end
13
+
14
+ it "should accept table name and column name to references" do
15
+ lambda { @target.references(@table_name, @column_name) }.should_not raise_error
16
+ end
17
+
18
+ it "should return an array" do
19
+ @target.references(@table_name, @column_name).should be_an(Array)
20
+ end
21
+
22
+ it "should split column name to table name and primary key" do
23
+ result = @target.references(@table_name, @column_name)
24
+ result[0].should eql @destination_table
25
+ result[1].should eql @destinantion_column
26
+ end
27
+
28
+ it "should handle parent_id as belonging to the same table" do
29
+ column_name = 'parent_id'
30
+ result = @target.references(@table_name, column_name)
31
+ result[0].should eql @table_name
32
+ result[1].should eql :id
33
+ end
34
+
35
+ it "should accept :references option which overrides default table name" do
36
+ result = @target.references(@table_name, @column_name, :references => 'users')
37
+ result[0].should eql 'users'
38
+ result[1].should eql :id
39
+ end
40
+
41
+ it "should accept :references option which overrides default table name and default column name" do
42
+ result = @target.references(@table_name, @column_name, :references => ['users', 'uuid'])
43
+ result[0].should eql 'users'
44
+ result[1].should eql 'uuid'
45
+ end
46
+
47
+ end
48
+
@@ -0,0 +1,24 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ create_table :users, :force => true do |t|
4
+ t.string :login
5
+ end
6
+ add_index :users, :login, :unique => true
7
+
8
+ create_table :members, :force => true do |t|
9
+ t.string :login
10
+ end
11
+
12
+ create_table :comments, :force => true do |t|
13
+ t.string :content
14
+ t.integer :user
15
+ t.integer :user_id
16
+ end
17
+
18
+ add_foreign_key :comments, :user_id, :users, :id
19
+
20
+ create_table :posts, :force => true do |t|
21
+ t.string :content
22
+ end
23
+
24
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'stringio'
3
+
4
+ require 'models/post'
5
+
6
+ describe "Schema dump" do
7
+
8
+ let(:dump) do
9
+ stream = StringIO.new
10
+ ActiveRecord::SchemaDumper.ignore_tables = []
11
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
12
+ stream.string
13
+ end
14
+
15
+ it "shouldn't include :index option for index" do
16
+ add_column(:author_id, :integer, :references => :users, :index => true) do
17
+ dump.should_not match(/index => true/)
18
+ end
19
+ end
20
+
21
+ protected
22
+ def add_column(column_name, *args)
23
+ table = Post.table_name
24
+ ActiveRecord::Migration.suppress_messages do
25
+ ActiveRecord::Migration.add_column(table, column_name, *args)
26
+ Post.reset_column_information
27
+ yield if block_given?
28
+ ActiveRecord::Migration.remove_column(table, column_name)
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,65 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe ActiveRecord::Schema do
4
+
5
+ let(:schema) { ActiveRecord::Schema }
6
+
7
+ let(:connection) { ActiveRecord::Base.connection }
8
+
9
+ after(:all) do
10
+ # revert to general schema
11
+ ActiveRecord::Migration.suppress_messages do
12
+ load 'schema/schema.rb'
13
+ end
14
+ end
15
+
16
+ context "defining with auto_index" do
17
+
18
+ it "should pass" do
19
+ with_auto_index do
20
+ expect { define_schema }.should_not raise_error
21
+ end
22
+ end
23
+
24
+ it "should create only explicity added indexes" do
25
+ with_auto_index do
26
+ define_schema
27
+ connection.tables.collect { |table| connection.indexes(table) }.flatten.should have_at_most(1).item
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ protected
34
+ def define_schema
35
+ ActiveRecord::Migration.suppress_messages do
36
+ schema.define do
37
+ create_table :users, :force => true do
38
+ end
39
+
40
+ create_table :posts, :force => true do |t|
41
+ t.integer :user_id
42
+ end
43
+
44
+ create_table :comments, :force => true do |t|
45
+ t.integer :user_id
46
+ end
47
+
48
+ # mysql will create index on FK automatically
49
+ unless ForeignKeyMigrationsHelpers.mysql?
50
+ add_index :posts, :user_id
51
+ add_index :comments, :user_id
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def with_auto_index(value = true)
58
+ old_value = ForeignKeyMigrations.auto_index
59
+ ForeignKeyMigrations.auto_index = value
60
+ yield
61
+ ensure
62
+ ForeignKeyMigrations.auto_index = old_value
63
+ end
64
+
65
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'rspec'
5
+ require 'foreign_key_migrations'
6
+ require 'connection'
7
+ Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
8
+
9
+ RSpec.configure do |config|
10
+ config.include(ForeignKeyMigrationsMatchers)
11
+ end
12
+
13
+ def load_schema
14
+ eval(File.read(File.join(File.dirname(__FILE__), 'schema', 'schema.rb')))
15
+ end
@@ -0,0 +1,8 @@
1
+ module ForeignKeyMigrationsHelpers
2
+ extend self
3
+
4
+ def mysql?
5
+ ActiveRecord::Base.connection.adapter_name =~ /^mysql/i
6
+ end
7
+
8
+ end
@@ -0,0 +1,2 @@
1
+ require 'support/matchers/reference'
2
+ require 'support/matchers/have_index'
@@ -0,0 +1,52 @@
1
+ module ForeignKeyMigrationsMatchers
2
+
3
+ class HaveIndex
4
+
5
+ def initialize(expectation, options = {})
6
+ set_required_columns(expectation, options)
7
+ end
8
+
9
+ def matches?(model)
10
+ @model = model
11
+ @model.indexes.any? do |index|
12
+ index.columns.to_set == @required_columns &&
13
+ (@unique ? index.unique : true) &&
14
+ (@name ? index.name == @name.to_s : true)
15
+ end
16
+ end
17
+
18
+ def failure_message_for_should(should_not = false)
19
+ invert = should_not ? "not to" : ""
20
+ "Expected #{@model.table_name} to #{invert} contain index on #{@required_columns.entries.inspect}"
21
+ end
22
+
23
+ def failure_message_for_should_not
24
+ failure_message_for_should(true)
25
+ end
26
+
27
+ def on(expectation)
28
+ set_required_columns(expectation)
29
+ self
30
+ end
31
+
32
+ private
33
+ def set_required_columns(expectation, options = {})
34
+ @required_columns = Array(expectation).collect(&:to_s).to_set
35
+ @unique = options.delete(:unique)
36
+ @name = options.delete(:name)
37
+ end
38
+
39
+ end
40
+
41
+ def have_index(*expectation)
42
+ options = expectation.extract_options!
43
+ HaveIndex.new(expectation, options)
44
+ end
45
+
46
+ def have_unique_index(*expectation)
47
+ options = expectation.extract_options!
48
+ options[:unique] = true
49
+ HaveIndex.new(expectation, options)
50
+ end
51
+
52
+ end
@@ -0,0 +1,66 @@
1
+ module ForeignKeyMigrationsMatchers
2
+
3
+ class Reference
4
+ def initialize(expected)
5
+ @column_names = nil
6
+ unless expected.empty?
7
+ @references_column_names = Array(expected).collect(&:to_s)
8
+ @references_table_name = @references_column_names.shift
9
+ end
10
+ end
11
+
12
+ def matches?(model)
13
+ @model = model
14
+ if @references_table_name
15
+ @result = @model.foreign_keys.select do |fk|
16
+ fk.references_table_name == @references_table_name &&
17
+ @references_column_names.empty? ? true : fk.references_column_names == @references_column_names
18
+ end
19
+ else
20
+ @result = @model.foreign_keys
21
+ end
22
+ if @column_names
23
+ @result.any? do |fk|
24
+ fk.column_names == @column_names &&
25
+ (@on_update ? fk.on_update == @on_update : true) &&
26
+ (@on_delete ? fk.on_delete == @on_delete : true)
27
+ end
28
+ else
29
+ !@result.empty?
30
+ end
31
+ end
32
+
33
+ def failure_message_for_should(should_not = false)
34
+ target_column_names = @column_names.present? ? "(#{@column_names.join(', ')})" : ""
35
+ destinantion_column_names = @references_table_name ? "#{@references_table_name}(#{@references_column_names.join(', ')})" : "anything"
36
+ invert = should_not ? 'not' : ''
37
+ "Expected #{@model.table_name}#{target_column_names} to #{invert} reference #{destinantion_column_names}"
38
+ end
39
+
40
+ def failure_message_for_should_not
41
+ failure_message_for_should(true)
42
+ end
43
+
44
+ def on(*column_names)
45
+ @column_names = column_names.collect(&:to_s)
46
+ self
47
+ end
48
+
49
+ def on_update(action)
50
+ @on_update = action
51
+ self
52
+ end
53
+
54
+ def on_delete(action)
55
+ @on_delete = action
56
+ self
57
+ end
58
+
59
+ end
60
+
61
+ def reference(*expect)
62
+ Reference.new(expect)
63
+ end
64
+
65
+ end
66
+
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aspgems-foreign_key_migrations
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: 6
5
+ version: 2.0.0.beta1
6
+ platform: ruby
7
+ authors:
8
+ - "Micha\xC5\x82 \xC5\x81omnicki"
9
+ - "Paco Guzm\xC3\xA1n"
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2011-05-14 00:00:00 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: aspgems-redhillonrails_core
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 2.0.0.beta2
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 2.5.0
36
+ type: :development
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: pg
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: mysql
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: mysql2
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ type: :development
70
+ version_requirements: *id005
71
+ description: Automatic Foreign Key automatically generates foreign-key constraints when creating tables or adding columns. It uses SQL-92 syntax and as such should be compatible with most databases that support foreign-key constraints.
72
+ email:
73
+ - michal.lomnicki@gmail.com
74
+ - fjguzman@aspgems.com
75
+ executables: []
76
+
77
+ extensions: []
78
+
79
+ extra_rdoc_files: []
80
+
81
+ files:
82
+ - .gitignore
83
+ - CHANGELOG
84
+ - Gemfile
85
+ - MIT-LICENSE
86
+ - README.md
87
+ - Rakefile
88
+ - foreign_key_migrations.gemspec
89
+ - init.rb
90
+ - install.rb
91
+ - lib/foreign_key_migrations.rb
92
+ - lib/foreign_key_migrations/active_record/base.rb
93
+ - lib/foreign_key_migrations/active_record/connection_adapters/schema_statements.rb
94
+ - lib/foreign_key_migrations/active_record/connection_adapters/table_definition.rb
95
+ - lib/foreign_key_migrations/active_record/migration.rb
96
+ - lib/foreign_key_migrations/version.rb
97
+ - lib/generators/foreign_key_migrations/migration_generator.rb
98
+ - lib/generators/foreign_key_migrations/templates/migration.rb
99
+ - spec/aaa_create_tables_spec.rb
100
+ - spec/connections/mysql/connection.rb
101
+ - spec/connections/mysql2/connection.rb
102
+ - spec/connections/postgresql/connection.rb
103
+ - spec/migration_spec.rb
104
+ - spec/models/comment.rb
105
+ - spec/models/post.rb
106
+ - spec/models/user.rb
107
+ - spec/references_spec.rb
108
+ - spec/schema/schema.rb
109
+ - spec/schema_dumper_spec.rb
110
+ - spec/schema_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/support/helpers.rb
113
+ - spec/support/matchers/foreign_key_migrations_matchers.rb
114
+ - spec/support/matchers/have_index.rb
115
+ - spec/support/matchers/reference.rb
116
+ homepage: https://github.com/aspgems/foreign_key_migrations
117
+ licenses: []
118
+
119
+ post_install_message:
120
+ rdoc_options: []
121
+
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: "0"
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">"
134
+ - !ruby/object:Gem::Version
135
+ version: 1.3.1
136
+ requirements: []
137
+
138
+ rubyforge_project:
139
+ rubygems_version: 1.7.2
140
+ signing_key:
141
+ specification_version: 3
142
+ summary: Automatically generate foreign-key constraints when creating tables
143
+ test_files: []
144
+