schema_plus 1.8.9 → 2.0.0.pre1

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -4
  3. data/.travis.yml +1 -47
  4. data/CHANGELOG.md +0 -35
  5. data/README.md +73 -107
  6. data/Rakefile +7 -10
  7. data/TODO.md +51 -0
  8. data/gemfiles/Gemfile.base +2 -0
  9. data/lib/schema_column_plus.rb +7 -0
  10. data/lib/{schema_plus → schema_column_plus}/active_record/connection_adapters/column.rb +13 -11
  11. data/lib/schema_column_plus/middleware/model.rb +22 -0
  12. data/lib/schema_db_default.rb +13 -0
  13. data/lib/{schema_plus → schema_db_default}/active_record/attribute.rb +4 -4
  14. data/lib/schema_db_default/db_default.rb +17 -0
  15. data/lib/schema_db_default/middleware.rb +30 -0
  16. data/lib/schema_default_expr.rb +32 -0
  17. data/lib/schema_default_expr/active_record/connection_adapters/mysql_adapter.rb +17 -0
  18. data/lib/schema_default_expr/active_record/connection_adapters/postgresql_adapter.rb +18 -0
  19. data/lib/schema_default_expr/active_record/connection_adapters/sqlite3_adapter.rb +35 -0
  20. data/lib/schema_default_expr/middleware.rb +54 -0
  21. data/lib/schema_pg_enums.rb +6 -0
  22. data/lib/schema_pg_enums/active_record.rb +69 -0
  23. data/lib/schema_pg_enums/middleware.rb +23 -0
  24. data/lib/schema_plus.rb +17 -45
  25. data/lib/schema_plus/active_record/base.rb +6 -23
  26. data/lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb +80 -181
  27. data/lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb +78 -99
  28. data/lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb +34 -114
  29. data/lib/schema_plus/active_record/connection_adapters/postgresql_adapter.rb +16 -370
  30. data/lib/schema_plus/active_record/connection_adapters/schema_statements.rb +1 -67
  31. data/lib/schema_plus/active_record/connection_adapters/sqlite3_adapter.rb +18 -112
  32. data/lib/schema_plus/active_record/connection_adapters/table_definition.rb +14 -116
  33. data/lib/schema_plus/active_record/migration/command_recorder.rb +8 -59
  34. data/lib/schema_plus/middleware/dumper.rb +94 -0
  35. data/lib/schema_plus/middleware/migration.rb +167 -0
  36. data/lib/schema_plus/middleware/model.rb +17 -0
  37. data/lib/schema_plus/version.rb +1 -1
  38. data/lib/schema_plus_tables.rb +15 -0
  39. data/lib/schema_plus_tables/active_record/connection_adapters/abstract_adapter.rb +20 -0
  40. data/lib/schema_plus_tables/active_record/connection_adapters/mysql_adapter.rb +25 -0
  41. data/lib/schema_plus_tables/active_record/connection_adapters/postgresql_adapter.rb +13 -0
  42. data/lib/schema_plus_tables/active_record/connection_adapters/sqlite3_adapter.rb +12 -0
  43. data/lib/schema_views.rb +16 -0
  44. data/lib/schema_views/active_record/connection_adapters/abstract_adapter.rb +41 -0
  45. data/lib/schema_views/active_record/connection_adapters/mysql_adapter.rb +30 -0
  46. data/lib/schema_views/active_record/connection_adapters/postgresql_adapter.rb +31 -0
  47. data/lib/schema_views/active_record/connection_adapters/sqlite3_adapter.rb +18 -0
  48. data/lib/schema_views/middleware.rb +47 -0
  49. data/schema_dev.yml +1 -31
  50. data/schema_plus.gemspec +11 -9
  51. data/spec/foreign_key_definition_spec.rb +7 -7
  52. data/spec/foreign_key_spec.rb +63 -48
  53. data/spec/migration_spec.rb +58 -203
  54. data/spec/named_schemas_spec.rb +5 -88
  55. data/spec/{column_spec.rb → schema_column_plus/column_spec.rb} +26 -48
  56. data/spec/schema_db_default/column_spec.rb +58 -0
  57. data/spec/{column_default_spec.rb → schema_default_expr/column_default_spec.rb} +1 -2
  58. data/spec/schema_default_expr/schema_dumper_spec.rb +116 -0
  59. data/spec/schema_dumper_spec.rb +22 -327
  60. data/spec/{enum_spec.rb → schema_pg_enums/enum_spec.rb} +1 -1
  61. data/spec/schema_pg_enums/schema_dumper_spec.rb +37 -0
  62. data/spec/schema_views/named_schemas_spec.rb +97 -0
  63. data/spec/{views_spec.rb → schema_views/views_spec.rb} +1 -1
  64. data/spec/spec_helper.rb +2 -1
  65. data/spec/support/matchers/reference.rb +11 -12
  66. metadata +104 -57
  67. data/gemfiles/rails-3.2/Gemfile.base +0 -3
  68. data/gemfiles/rails-3.2/Gemfile.mysql +0 -10
  69. data/gemfiles/rails-3.2/Gemfile.mysql2 +0 -10
  70. data/gemfiles/rails-3.2/Gemfile.postgresql +0 -10
  71. data/gemfiles/rails-3.2/Gemfile.sqlite3 +0 -10
  72. data/gemfiles/rails-4.0/Gemfile.base +0 -3
  73. data/gemfiles/rails-4.0/Gemfile.mysql2 +0 -10
  74. data/gemfiles/rails-4.0/Gemfile.postgresql +0 -10
  75. data/gemfiles/rails-4.0/Gemfile.sqlite3 +0 -10
  76. data/gemfiles/rails-4.1/Gemfile.base +0 -3
  77. data/gemfiles/rails-4.1/Gemfile.mysql2 +0 -10
  78. data/gemfiles/rails-4.1/Gemfile.postgresql +0 -10
  79. data/gemfiles/rails-4.1/Gemfile.sqlite3 +0 -10
  80. data/lib/schema_plus/active_record/column_options_handler.rb +0 -117
  81. data/lib/schema_plus/active_record/connection_adapters/index_definition.rb +0 -70
  82. data/lib/schema_plus/active_record/db_default.rb +0 -19
  83. data/lib/schema_plus/active_record/foreign_keys.rb +0 -137
  84. data/lib/schema_plus/active_record/schema_dumper.rb +0 -171
  85. data/lib/schema_plus/railtie.rb +0 -20
  86. data/spec/index_definition_spec.rb +0 -211
  87. data/spec/index_spec.rb +0 -249
@@ -0,0 +1,31 @@
1
+ module SchemaViews
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module PostgresqlAdapter
5
+
6
+ def views(name = nil) #:nodoc:
7
+ sql = <<-SQL
8
+ SELECT viewname
9
+ FROM pg_views
10
+ WHERE schemaname = ANY (current_schemas(false))
11
+ AND viewname NOT LIKE 'pg\_%'
12
+ SQL
13
+ sql += " AND schemaname != 'postgis'" if adapter_name == 'PostGIS'
14
+ query(sql, name).map { |row| row[0] }
15
+ end
16
+
17
+ def view_definition(view_name, name = nil) #:nodoc:
18
+ result = query(<<-SQL, name)
19
+ SELECT pg_get_viewdef(oid)
20
+ FROM pg_class
21
+ WHERE relkind = 'v'
22
+ AND relname = '#{view_name}'
23
+ SQL
24
+ row = result.first
25
+ row.first.chomp(';') unless row.nil?
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module SchemaViews
2
+ module ActiveRecord
3
+ module ConnectionAdapters
4
+ module Sqlite3Adapter
5
+
6
+ def views(name = nil)
7
+ execute("SELECT name FROM sqlite_master WHERE type='view'", name).collect{|row| row["name"]}
8
+ end
9
+
10
+ def view_definition(view_name, name = nil)
11
+ sql = execute("SELECT sql FROM sqlite_master WHERE type='view' AND name=#{quote(view_name)}", name).collect{|row| row["sql"]}.first
12
+ sql.sub(/^CREATE VIEW \S* AS\s+/im, '') unless sql.nil?
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ module SchemaViews
2
+ module Middleware
3
+ def self.insert
4
+ SchemaMonkey::Middleware::Dumper::Tables.prepend DumpViews
5
+ end
6
+ module Mysql
7
+ def self.insert
8
+ SchemaMonkey::Middleware::Query::Tables.append FilterOutViews
9
+ end
10
+ end
11
+ module Sqlite3
12
+ def self.insert
13
+ SchemaMonkey::Middleware::Query::Tables.append FilterOutViews
14
+ end
15
+ end
16
+ end
17
+
18
+ class FilterOutViews < SchemaMonkey::Middleware::Base
19
+ def call(env)
20
+ continue env
21
+ env.tables -= env.connection.views(env.query_name)
22
+ end
23
+ end
24
+
25
+ class DumpViews < SchemaMonkey::Middleware::Base
26
+
27
+ # quacks like a SchemaMonkey Dump::Table
28
+ class View < KeyStruct[:name, :definition]
29
+ def assemble(stream)
30
+ stream.puts(" create_view #{name.inspect}, #{definition.inspect}, :force => true\n")
31
+ end
32
+ end
33
+
34
+ def call(env)
35
+ continue env
36
+
37
+ re_view_referent = %r{(?:(?i)FROM|JOIN) \S*\b(\S+)\b}
38
+ env.connection.views.each do |view_name|
39
+ next if env.dumper.ignored?(view_name)
40
+ view = View.new(name: view_name, definition: env.connection.view_definition(view_name))
41
+ env.dump.tables[view.name] = view
42
+ env.dump.depends(view.name, view.definition.scan(re_view_referent).flatten)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -1,39 +1,9 @@
1
1
  ruby:
2
- - jruby
3
2
  - 1.9.3
4
- - 2.1.3
3
+ - 2.1.5
5
4
  rails:
6
- - 3.2
7
- - 4.0
8
- - 4.1
9
5
  - 4.2
10
6
  db:
11
- - mysql
12
7
  - mysql2
13
8
  - sqlite3
14
9
  - postgresql
15
- exclude:
16
- -
17
- rails: 4.0
18
- db: mysql
19
- -
20
- rails: 4.1
21
- db: mysql
22
- -
23
- rails: 4.2
24
- db: mysql
25
- -
26
- ruby: jruby
27
- rails: 4.0
28
- -
29
- ruby: jruby
30
- rails: 4.1
31
- -
32
- ruby: jruby
33
- rails: 4.2
34
- -
35
- ruby: jruby
36
- db: sqlite3
37
- -
38
- ruby: jruby
39
- db: postgresql
@@ -21,15 +21,17 @@ Gem::Specification.new do |s|
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
22
  s.require_paths = ["lib"]
23
23
 
24
- s.add_dependency("activerecord", ">= 3.2", "<= 4.2.0")
25
- s.add_dependency("valuable")
24
+ s.add_dependency "activerecord", ">= 3.2", "< 4.3"
25
+ s.add_dependency "valuable"
26
+ s.add_dependency "schema_monkey", "~> 0.1"
27
+ s.add_dependency "schema_plus_indexes", "~> 0.1"
28
+ s.add_dependency "schema_plus_pg_indexes", "~> 0.1"
26
29
 
27
- s.add_development_dependency("schema_dev", "~> 1.4")
28
- s.add_development_dependency("rake")
29
- s.add_development_dependency("rspec", "~> 3.0.0")
30
- s.add_development_dependency("rdoc")
31
- s.add_development_dependency("simplecov")
32
- s.add_development_dependency("simplecov-gem-profile")
33
- s.add_development_dependency("its-it")
30
+ s.add_development_dependency "schema_dev", "~> 2.0", ">= 2.0.3"
31
+ s.add_development_dependency "rake"
32
+ s.add_development_dependency "rspec", "~> 3.0.0"
33
+ s.add_development_dependency "rdoc"
34
+ s.add_development_dependency "simplecov"
35
+ s.add_development_dependency "simplecov-gem-profile"
34
36
  end
35
37
 
@@ -1,10 +1,10 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
2
2
 
3
3
  describe "Foreign Key definition" do
4
4
 
5
5
  let(:definition) {
6
- options = {:name => "posts_user_fkey", :column_names => :user, :references_column_names => :id}
7
- SchemaPlus::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(:posts, :users, options)
6
+ options = {:name => "posts_user_fkey", :column => :user, :primary_key => :id}
7
+ ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(:posts, :users, options)
8
8
  }
9
9
 
10
10
  it "dumps to sql with quoted values" do
@@ -12,14 +12,14 @@ describe "Foreign Key definition" do
12
12
  end
13
13
 
14
14
  it "dumps to sql with deferrable values" do
15
- options = {:name => "posts_user_fkey", :column_names => :user, :references_column_names => :id, :deferrable => true}
16
- deferred_definition = SchemaPlus::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(:posts, :users, options)
15
+ options = {:name => "posts_user_fkey", :column => :user, :primary_key => :id, :deferrable => true}
16
+ deferred_definition = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(:posts, :users, options)
17
17
  expect(deferred_definition.to_sql).to eq(%Q{CONSTRAINT posts_user_fkey FOREIGN KEY (#{quote_column_name('user')}) REFERENCES #{quote_table_name('users')} (#{quote_column_name('id')}) DEFERRABLE})
18
18
  end
19
19
 
20
20
  it "dumps to sql with initially deferrable values" do
21
- options = {:name => "posts_user_fkey", :column_names => :user, :references_column_names => :id, :deferrable => :initially_deferred}
22
- initially_deferred_definition = SchemaPlus::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(:posts, :users, options)
21
+ options = {:name => "posts_user_fkey", :column => :user, :primary_key => :id, :deferrable => :initially_deferred}
22
+ initially_deferred_definition = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(:posts, :users, options)
23
23
  expect(initially_deferred_definition.to_sql).to eq(%Q{CONSTRAINT posts_user_fkey FOREIGN KEY (#{quote_column_name('user')}) REFERENCES #{quote_table_name('users')} (#{quote_column_name('id')}) DEFERRABLE INITIALLY DEFERRED})
24
24
  end
25
25
 
@@ -12,7 +12,7 @@ describe "Foreign Key" do
12
12
  end
13
13
  create_table :comments, :force => true do |t|
14
14
  t.integer :user_id
15
- t.foreign_key :user_id, :users, :id
15
+ t.foreign_key :user_id, :users
16
16
  end
17
17
  end
18
18
  class User < ::ActiveRecord::Base ; end
@@ -20,42 +20,40 @@ describe "Foreign Key" do
20
20
  end
21
21
 
22
22
  it "should report foreign key constraints" do
23
- expect(Comment.foreign_keys.collect(&:column_names).flatten).to eq([ "user_id" ])
23
+ expect(Comment.foreign_keys.collect(&:column).flatten).to eq([ "user_id" ])
24
24
  end
25
25
 
26
26
  it "should report reverse foreign key constraints" do
27
- expect(User.reverse_foreign_keys.collect(&:column_names).flatten).to eq([ "user_id" ])
27
+ expect(User.reverse_foreign_keys.collect(&:column).flatten).to eq([ "user_id" ])
28
28
  end
29
29
 
30
30
  end
31
31
 
32
- if ::ActiveRecord::VERSION::MAJOR.to_i >= 4
33
- context "with modifications to SQL generated by upstream visit_TableDefinition" do
34
- before(:each) do
35
- allow_any_instance_of(ActiveRecord::Base.connection.class.const_get(:SchemaCreation))
36
- .to receive(:visit_TableDefinition_without_schema_plus)
37
- .and_return('this is unexpected')
38
- end
32
+ context "with modifications to SQL generated by upstream visit_TableDefinition" do
33
+ before(:each) do
34
+ allow_any_instance_of(ActiveRecord::Base.connection.class.const_get(:SchemaCreation))
35
+ .to receive(:visit_TableDefinition_without_schema_plus)
36
+ .and_return('this is unexpected')
37
+ end
39
38
 
40
- it "raises an exception when attempting to create a table" do
41
- expect {
42
- define_schema(:auto_create => true) do
43
- create_table :users, :force => true do |t|
44
- t.string :login
45
- end
46
- create_table :comments, :force => true do |t|
47
- t.integer :user_id
48
- t.foreign_key :user_id, :users, :id
49
- end
39
+ it "raises an exception when attempting to create a table" do
40
+ expect {
41
+ define_schema(:auto_create => true) do
42
+ create_table :users, :force => true do |t|
43
+ t.string :login
50
44
  end
51
- }.to raise_error(RuntimeError, /Internal Error: Can't find.*Rails internals have changed/)
52
- end
45
+ create_table :comments, :force => true do |t|
46
+ t.integer :user_id
47
+ t.foreign_key :user_id, :users
48
+ end
49
+ end
50
+ }.to raise_error(RuntimeError, /Internal Error: Can't find.*Rails internals have changed/)
53
51
  end
54
52
  end
55
53
 
56
54
  context "modification" do
57
55
 
58
- before(:all) do
56
+ before(:each) do
59
57
  define_schema(:auto_create => false) do
60
58
  create_table :users, :force => true do |t|
61
59
  t.string :login
@@ -71,12 +69,13 @@ describe "Foreign Key" do
71
69
  create_table :comments, :force => true do |t|
72
70
  t.text :body
73
71
  t.integer :post_id
74
- t.foreign_key :post_id, :posts, :id
72
+ t.foreign_key :post_id, :posts
75
73
  end
76
74
  end
77
75
  class User < ::ActiveRecord::Base ; end
78
76
  class Post < ::ActiveRecord::Base ; end
79
77
  class Comment < ::ActiveRecord::Base ; end
78
+ Comment.reset_column_information
80
79
  end
81
80
 
82
81
 
@@ -85,12 +84,7 @@ describe "Foreign Key" do
85
84
  context "when is added", "posts(author_id)" do
86
85
 
87
86
  before(:each) do
88
- add_foreign_key(:posts, :author_id, :users, :id, :on_update => :cascade, :on_delete => :restrict)
89
- end
90
-
91
- after(:each) do
92
- fk = Post.foreign_keys.detect(&its.column_names == %w[author_id])
93
- remove_foreign_key(:posts, fk.name)
87
+ add_foreign_key(:posts, :users, :column => :author_id, :on_update => :cascade, :on_delete => :restrict)
94
88
  end
95
89
 
96
90
  it "references users(id)" do
@@ -106,25 +100,21 @@ describe "Foreign Key" do
106
100
  end
107
101
 
108
102
  it "is available in Post.foreign_keys" do
109
- expect(Post.foreign_keys.collect(&:column_names)).to include(%w[author_id])
103
+ expect(Post.foreign_keys.collect(&:column)).to include('author_id')
110
104
  end
111
105
 
112
106
  it "is available in User.reverse_foreign_keys" do
113
- expect(User.reverse_foreign_keys.collect(&:column_names)).to include(%w[author_id])
107
+ expect(User.reverse_foreign_keys.collect(&:column)).to include('author_id')
114
108
  end
115
109
 
116
110
  end
117
111
 
118
112
  context "when is dropped", "comments(post_id)" do
119
113
 
120
- let(:foreign_key_name) { fk = Comment.foreign_keys.detect(&its.column_names == %w[post_id]) and fk.name }
114
+ let(:foreign_key_name) { fk = Comment.foreign_keys.detect(&its.column == 'post_id') and fk.name }
121
115
 
122
116
  before(:each) do
123
- remove_foreign_key(:comments, foreign_key_name)
124
- end
125
-
126
- after(:each) do
127
- add_foreign_key(:comments, :post_id, :posts, :id)
117
+ remove_foreign_key(:comments, name: foreign_key_name)
128
118
  end
129
119
 
130
120
  it "doesn't reference posts(id)" do
@@ -132,22 +122,47 @@ describe "Foreign Key" do
132
122
  end
133
123
 
134
124
  it "is no longer available in Post.foreign_keys" do
135
- expect(Comment.foreign_keys.collect(&:column_names)).not_to include(%w[post_id])
125
+ expect(Comment.foreign_keys.collect(&:column)).not_to include('post_id')
136
126
  end
137
127
 
138
128
  it "is no longer available in User.reverse_foreign_keys" do
139
- expect(Post.reverse_foreign_keys.collect(&:column_names)).not_to include(%w[post_id])
129
+ expect(Post.reverse_foreign_keys.collect(&:column)).not_to include('post_id')
140
130
  end
141
131
 
142
132
  end
143
133
 
134
+ context "when drop using hash", "comments(post_id)" do
135
+
136
+ let(:foreign_key_name) { fk = Comment.foreign_keys.detect(&its.column == 'post_id') and fk.name }
137
+
138
+ it "finds by name" do
139
+ remove_foreign_key(:comments, name: foreign_key_name)
140
+ expect(Comment).not_to reference(:posts).on(:post_id)
141
+ end
142
+
143
+ it "finds by column_names" do
144
+ remove_foreign_key(:comments, column: "post_id", to_table: "posts")
145
+ expect(Comment).not_to reference(:posts).on(:post_id)
146
+ end
147
+ end
148
+
149
+ context "when attempt to drop nonexistent foreign key" do
150
+ it "raises error" do
151
+ expect{remove_foreign_key(:comments, "posts", column: "nonesuch")}.to raise_error(/no foreign key/i)
152
+ end
153
+
154
+ it "does not error with :if_exists" do
155
+ expect{remove_foreign_key(:comments, "posts", column: "nonesuch", :if_exists => true)}.to_not raise_error
156
+ end
157
+ end
158
+
144
159
  context "when referencing column and column is removed" do
145
160
 
146
- let(:foreign_key_name) { Comment.foreign_keys.detect { |definition| definition.column_names == %w[post_id] }.name }
161
+ let(:foreign_key_name) { Comment.foreign_keys.detect { |definition| definition.column == 'post_id' }.name }
147
162
 
148
163
  it "should remove foreign keys" do
149
- remove_foreign_key(:comments, foreign_key_name)
150
- expect(Post.reverse_foreign_keys.collect { |fk| fk.column_names == %w[post_id] && fk.table_name == "comments" }).to be_empty
164
+ remove_foreign_key(:comments, name: foreign_key_name)
165
+ expect(Post.reverse_foreign_keys.collect { |fk| fk.column == 'post_id' && fk.from_table == "comments" }).to be_empty
151
166
  end
152
167
 
153
168
  end
@@ -164,9 +179,9 @@ describe "Foreign Key" do
164
179
  it "can add, detect, and remove a foreign key without error" do
165
180
  migration.suppress_messages do
166
181
  expect {
167
- migration.add_foreign_key(:references, :post_id, :posts, :id)
168
- foreign_key = migration.foreign_keys(:references).detect{|definition| definition.column_names == ["post_id"]}
169
- migration.remove_foreign_key(:references, foreign_key.name)
182
+ migration.add_foreign_key(:references, :posts)
183
+ foreign_key = migration.foreign_keys(:references).detect{|definition| definition.column == "post_id"}
184
+ migration.remove_foreign_key(:references, name: foreign_key.name)
170
185
  }.to_not raise_error
171
186
  end
172
187
  end
@@ -178,13 +193,13 @@ describe "Foreign Key" do
178
193
 
179
194
  it "when attempting to add" do
180
195
  expect {
181
- add_foreign_key(:posts, :author_id, :users, :id, :on_update => :cascade, :on_delete => :restrict)
196
+ add_foreign_key(:posts, :users, :column => :author_id, :on_update => :cascade, :on_delete => :restrict)
182
197
  }.to raise_error(NotImplementedError)
183
198
  end
184
199
 
185
200
  it "when attempting to remove" do
186
201
  expect {
187
- remove_foreign_key(:posts, "dummy")
202
+ remove_foreign_key(:posts, name: "dummy")
188
203
  }.to raise_error(NotImplementedError)
189
204
  end
190
205
 
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'spec_helper'
3
3
 
4
4
  describe ActiveRecord::Migration do
5
5
 
@@ -18,7 +18,7 @@ describe ActiveRecord::Migration do
18
18
  t.string :content
19
19
  t.integer :user
20
20
  t.integer :user_id
21
- t.foreign_key :user_id, :users, :id
21
+ t.foreign_key :user_id, :users, :primary_key => :id
22
22
  end
23
23
 
24
24
  create_table :posts, :force => true do |t|
@@ -172,27 +172,6 @@ describe ActiveRecord::Migration do
172
172
  expect(@model).to reference(@model.table_name, :id).on(:parent_id)
173
173
  end
174
174
 
175
- it "should create an index if specified on column" do
176
- recreate_table(@model) do |t|
177
- t.integer :state, :index => true
178
- end
179
- expect(@model).to have_index.on(:state)
180
- end
181
-
182
- it "should create a unique index if specified on column" do
183
- recreate_table(@model) do |t|
184
- t.integer :state, :index => { :unique => true }
185
- end
186
- expect(@model).to have_unique_index.on(:state)
187
- end
188
-
189
- it "should create a unique index if specified on column using shorthand" do
190
- recreate_table(@model) do |t|
191
- t.integer :state, :index => :unique
192
- end
193
- expect(@model).to have_unique_index.on(:state)
194
- end
195
-
196
175
  [:references, :belongs_to].each do |reftype|
197
176
 
198
177
  context "when define #{reftype}" do
@@ -229,7 +208,7 @@ describe ActiveRecord::Migration do
229
208
  it "should create a two-column index if polymophic and index requested" do
230
209
  create_reference(reftype, :post, :polymorphic => true, :index => true)
231
210
  expect(@model).to have_index.on([:post_id, :post_type])
232
- end unless ::ActiveRecord::VERSION::MAJOR.to_i < 4
211
+ end
233
212
 
234
213
  protected
235
214
 
@@ -242,49 +221,6 @@ describe ActiveRecord::Migration do
242
221
  end
243
222
  end
244
223
 
245
- it "should pass index length option properly", :mysql => :only do
246
- recreate_table(@model) do |t|
247
- t.string :foo
248
- t.string :bar, :index => { :with => :foo, :length => { :foo => 8, :bar => 12 }}
249
- end
250
- index = @model.indexes.first
251
- expect(Hash[index.columns.zip(index.lengths.map(&:to_i))]).to eq({ "foo" => 8, "bar" => 12})
252
- end
253
-
254
- it "should create an index if specified explicitly" do
255
- recreate_table(@model) do |t|
256
- t.integer :state
257
- t.index :state
258
- end
259
- expect(@model).to have_index.on(:state)
260
- end
261
-
262
- it "should create a unique index if specified explicitly" do
263
- recreate_table(@model) do |t|
264
- t.integer :state
265
- t.index :state, :unique => true
266
- end
267
- expect(@model).to have_unique_index.on(:state)
268
- end
269
-
270
- it "should create a multiple-column index if specified" do
271
- recreate_table(@model) do |t|
272
- t.integer :city
273
- t.integer :state, :index => { :with => :city }
274
- end
275
- expect(@model).to have_index.on([:state, :city])
276
- end
277
-
278
- it "should create the index without modifying the input hash" do
279
- hash = { :with => :foo, :length => { :foo => 8, :bar => 12 }}
280
- hash_original = hash.dup
281
- recreate_table(@model) do |t|
282
- t.string :foo
283
- t.string :bar, :index => hash
284
- end
285
- expect(hash).to eq(hash_original)
286
- end
287
-
288
224
  it "should auto-index foreign keys only" do
289
225
  recreate_table(@model) do |t|
290
226
  t.integer :user_id
@@ -323,7 +259,7 @@ describe ActiveRecord::Migration do
323
259
  end
324
260
  end
325
261
 
326
- actions = [:cascade, :restrict, :set_null, :set_default, :no_action]
262
+ actions = [:cascade, :restrict, :nullify, :set_default, :no_action]
327
263
 
328
264
  actions.each do |action|
329
265
  if action == :set_default
@@ -419,18 +355,18 @@ describe ActiveRecord::Migration do
419
355
  it "should override on_update action per column" do
420
356
  with_fk_config(:on_update => :cascade) do
421
357
  recreate_table @model, :foreign_keys => {:on_update => :restrict} do |t|
422
- t.integer :user_id, :foreign_key => { :on_update => :set_null }
358
+ t.integer :user_id, :foreign_key => { :on_update => :nullify }
423
359
  end
424
- expect(@model).to reference.on(:user_id).on_update(:set_null)
360
+ expect(@model).to reference.on(:user_id).on_update(:nullify)
425
361
  end
426
362
  end
427
363
 
428
364
  it "should override on_delete action per column" do
429
365
  with_fk_config(:on_delete => :cascade) do
430
366
  recreate_table @model, :foreign_keys => {:on_delete => :restrict} do |t|
431
- t.integer :user_id, :foreign_key => { :on_delete => :set_null }
367
+ t.integer :user_id, :foreign_key => { :on_delete => :nullify }
432
368
  end
433
- expect(@model).to reference.on(:user_id).on_delete(:set_null)
369
+ expect(@model).to reference.on(:user_id).on_delete(:nullify)
434
370
  end
435
371
  end
436
372
 
@@ -477,13 +413,6 @@ describe ActiveRecord::Migration do
477
413
  [false, true].each do |bulk|
478
414
  suffix = bulk ? ' with :bulk option' : ""
479
415
 
480
- it "should create an index if specified on column"+suffix do
481
- change_table(@model, :bulk => bulk) do |t|
482
- t.integer :state, :index => true
483
- end
484
- expect(@model).to have_index.on(:state)
485
- end
486
-
487
416
  it "should create a foreign key constraint"+suffix, :sqlite3 => :skip do
488
417
  change_table(@model, :bulk => bulk) do |t|
489
418
  t.integer :user_id
@@ -508,7 +437,7 @@ describe ActiveRecord::Migration do
508
437
  Comment.reset_column_information
509
438
  expect(Comment).not_to reference(:users, :id).on(:user_id)
510
439
  end
511
- end if ActiveRecord::VERSION::MAJOR >= 4
440
+ end
512
441
 
513
442
  it "should create a foreign key constraint using :references"+suffix, :sqlite3 => :skip do
514
443
  change_table(@model, :bulk => bulk) do |t|
@@ -542,12 +471,6 @@ describe ActiveRecord::Migration do
542
471
  @model = Comment
543
472
  end
544
473
 
545
- it "should create an index" do
546
- add_column(:slug, :string, :index => true) do
547
- expect(@model).to have_index.on(:slug)
548
- end
549
- end
550
-
551
474
  it "should create foreign key" do
552
475
  add_column(:post_id, :integer) do
553
476
  expect(@model).to reference(:posts, :id).on(:post_id)
@@ -596,31 +519,6 @@ describe ActiveRecord::Migration do
596
519
  end
597
520
  end
598
521
 
599
- it "should create an index if specified" do
600
- add_column(:post_id, :integer, :index => true) do
601
- expect(@model).to have_index.on(:post_id)
602
- end
603
- end
604
-
605
- it "should create a unique index if specified" do
606
- add_column(:post_id, :integer, :index => { :unique => true }) do
607
- expect(@model).to have_unique_index.on(:post_id)
608
- end
609
- end
610
-
611
- it "should create a unique index if specified by shorthand" do
612
- add_column(:post_id, :integer, :index => :unique) do
613
- expect(@model).to have_unique_index.on(:post_id)
614
- end
615
- end
616
-
617
- it "should allow custom name for index" do
618
- index_name = 'comments_post_id_unique_index'
619
- add_column(:post_id, :integer, :index => { :unique => true, :name => index_name }) do
620
- expect(@model).to have_unique_index(:name => index_name).on(:post_id)
621
- end
622
- end
623
-
624
522
  it "should auto-index if specified in global options" do
625
523
  SchemaPlus.config.foreign_keys.auto_index = true
626
524
  add_column(:post_id, :integer) do
@@ -665,8 +563,8 @@ describe ActiveRecord::Migration do
665
563
  it "should allow to overwrite default actions" do
666
564
  SchemaPlus.config.foreign_keys.on_delete = :cascade
667
565
  SchemaPlus.config.foreign_keys.on_update = :restrict
668
- add_column(:post_id, :integer, :foreign_key => { :on_update => :set_null, :on_delete => :set_null}) do
669
- expect(@model).to reference.on(:post_id).on_delete(:set_null).on_update(:set_null)
566
+ add_column(:post_id, :integer, :foreign_key => { :on_update => :nullify, :on_delete => :nullify}) do
567
+ expect(@model).to reference.on(:post_id).on_delete(:nullify).on_update(:nullify)
670
568
  end
671
569
  SchemaPlus.config.foreign_keys.on_delete = nil
672
570
  end
@@ -685,96 +583,78 @@ describe ActiveRecord::Migration do
685
583
  end
686
584
 
687
585
 
688
- context "when changing a column" do
586
+ context "when column is changed", :sqlite3 => :skip do
689
587
 
690
588
  before(:each) do
691
589
  @model = Comment
692
590
  end
693
591
 
694
- context "with foreign keys", :sqlite3 => :skip do
695
-
696
- it "should create foreign key" do
697
- change_column :user, :string, :foreign_key => { :references => [:users, :login] }
698
- expect(@model).to reference(:users, :login).on(:user)
699
- end
592
+ it "should create foreign key" do
593
+ change_column :user, :string, :foreign_key => { :references => [:users, :login] }
594
+ expect(@model).to reference(:users, :login).on(:user)
595
+ end
700
596
 
701
- context "and initially references to users table" do
597
+ context "and initially references to users table" do
702
598
 
703
- before(:each) do
704
- recreate_table @model do |t|
705
- t.integer :user_id
706
- end
599
+ before(:each) do
600
+ recreate_table @model do |t|
601
+ t.integer :user_id
707
602
  end
603
+ end
708
604
 
709
- it "should have foreign key" do
710
- expect(@model).to reference(:users)
711
- end
605
+ it "should have foreign key" do
606
+ expect(@model).to reference(:users)
607
+ end
712
608
 
713
- it "should drop foreign key if it is no longer valid" do
714
- change_column :user_id, :integer, :foreign_key => { :references => :members }
715
- expect(@model).not_to reference(:users)
716
- end
609
+ it "should drop foreign key if it is no longer valid" do
610
+ change_column :user_id, :integer, :foreign_key => { :references => :members }
611
+ expect(@model).not_to reference(:users)
612
+ end
717
613
 
718
- it "should drop foreign key if requested to do so" do
719
- change_column :user_id, :integer, :foreign_key => { :references => nil }
720
- expect(@model).not_to reference(:users)
721
- end
614
+ it "should drop foreign key if requested to do so" do
615
+ change_column :user_id, :integer, :foreign_key => { :references => nil }
616
+ expect(@model).not_to reference(:users)
617
+ end
722
618
 
723
- it "should remove auto-created index if foreign key is removed" do
724
- expect(@model).to have_index.on(:user_id) # sanity check that index was auto-created
725
- change_column :user_id, :integer, :foreign_key => { :references => nil }
726
- expect(@model).not_to have_index.on(:user_id)
727
- end
619
+ it "should remove auto-created index if foreign key is removed" do
620
+ expect(@model).to have_index.on(:user_id) # sanity check that index was auto-created
621
+ change_column :user_id, :integer, :foreign_key => { :references => nil }
622
+ expect(@model).not_to have_index.on(:user_id)
623
+ end
728
624
 
729
- it "should reference pointed table afterwards if new one is created" do
730
- change_column :user_id, :integer, :foreign_key => { :references => :members }
731
- expect(@model).to reference(:members)
732
- end
625
+ it "should reference pointed table afterwards if new one is created" do
626
+ change_column :user_id, :integer, :foreign_key => { :references => :members }
627
+ expect(@model).to reference(:members)
628
+ end
733
629
 
734
- it "should maintain foreign key if it's unaffected by change" do
630
+ it "should maintain foreign key if it's unaffected by change" do
631
+ change_column :user_id, :integer, :default => 0
632
+ expect(@model).to reference(:users)
633
+ end
634
+
635
+ it "should maintain foreign key if it's unaffected by change, even if auto_index is off" do
636
+ with_fk_config(:auto_create => false) do
735
637
  change_column :user_id, :integer, :default => 0
736
638
  expect(@model).to reference(:users)
737
639
  end
738
-
739
- it "should maintain foreign key if it's unaffected by change, even if auto_index is off" do
740
- with_fk_config(:auto_create => false) do
741
- change_column :user_id, :integer, :default => 0
742
- expect(@model).to reference(:users)
743
- end
744
- end
745
-
746
640
  end
747
641
 
748
- context "if column defined without foreign key but with index" do
749
- before(:each) do
750
- recreate_table @model do |t|
751
- t.integer :user_id, :foreign_key => false, :index => true
752
- end
753
- end
754
-
755
- it "should create the index" do
756
- expect(@model).to have_index.on(:user_id)
757
- end
758
-
759
- it "adding foreign key should not fail due to attempt to auto-create existing index" do
760
- expect { change_column :user_id, :integer, :foreign_key => true }.to_not raise_error
761
- end
762
- end
763
642
  end
764
643
 
765
- context "without foreign keys" do
766
-
767
- it "doesn't auto-add foreign keys" do
644
+ context "if column defined without foreign key but with index" do
645
+ before(:each) do
768
646
  recreate_table @model do |t|
769
- t.integer :user_id, :foreign_key => false
770
- t.string :other_column
771
- end
772
- with_fk_auto_create do
773
- change_column :other_column, :text
647
+ t.integer :user_id, :foreign_key => false, :index => true
774
648
  end
775
- expect(@model).to_not reference(:users)
776
649
  end
777
650
 
651
+ it "should create the index" do
652
+ expect(@model).to have_index.on(:user_id)
653
+ end
654
+
655
+ it "adding foreign key should not fail due to attempt to auto-create existing index" do
656
+ expect { change_column :user_id, :integer, :foreign_key => true }.to_not raise_error
657
+ end
778
658
  end
779
659
 
780
660
  protected
@@ -788,7 +668,6 @@ describe ActiveRecord::Migration do
788
668
 
789
669
  end
790
670
 
791
-
792
671
  context "when column is removed", :sqlite3 => :skip do
793
672
  before(:each) do
794
673
  @model = Comment
@@ -833,21 +712,6 @@ describe ActiveRecord::Migration do
833
712
  end
834
713
  end
835
714
 
836
- around(:each) do |example|
837
- begin
838
- example.run
839
- ensure
840
- ActiveRecord::Migration.suppress_messages do
841
- ActiveRecord::Migration.rename_table :newname, :comments
842
- end
843
- end
844
- end
845
-
846
- it "should rename rails-named indexes" do
847
- index = ActiveRecord::Base.connection.indexes(:newname).find(&its.columns == ['xyz'])
848
- expect(index.name).to match(/^index_newname_on/)
849
- end
850
-
851
715
  it "should rename fk indexes" do
852
716
  index = ActiveRecord::Base.connection.indexes(:newname).find(&its.columns == ['user_id'])
853
717
  expect(index.name).to match(/^fk__newname_/)
@@ -873,15 +737,6 @@ describe ActiveRecord::Migration do
873
737
  end
874
738
  end
875
739
 
876
- around(:each) do |example|
877
- begin
878
- example.run
879
- ensure
880
- ActiveRecord::Migration.suppress_messages do
881
- ActiveRecord::Migration.rename_table :newname, :comments
882
- end
883
- end
884
- end
885
740
  it "should rename foreign key constraints" do
886
741
  names = ActiveRecord::Base.connection.foreign_keys(:newname).map(&:name)
887
742
  expect(names.grep(/newname/)).to eq(names)