schema_plus 2.0.0.pre16 → 2.0.0
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.
- checksums.yaml +4 -4
- data/README.md +41 -58
- data/lib/schema_plus.rb +1 -1
- data/lib/schema_plus/version.rb +1 -1
- data/schema_plus.gemspec +3 -3
- data/spec/sanity_spec.rb +10 -0
- metadata +15 -27
- data/lib/schema_plus/auto_foreign_keys.rb +0 -31
- data/lib/schema_plus/auto_foreign_keys/active_record/connection_adapters/sqlite3_adapter.rb +0 -22
- data/lib/schema_plus/auto_foreign_keys/active_record/migration/command_recorder.rb +0 -14
- data/lib/schema_plus/auto_foreign_keys/middleware/migration.rb +0 -66
- data/lib/schema_plus/auto_foreign_keys/middleware/schema.rb +0 -18
- data/spec/schema_auto_foreign_keys/foreign_key_spec.rb +0 -206
- data/spec/schema_auto_foreign_keys/migration_spec.rb +0 -778
- data/spec/schema_auto_foreign_keys/schema_dumper_spec.rb +0 -256
- data/spec/schema_auto_foreign_keys/schema_spec.rb +0 -99
@@ -1,256 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
describe "Schema dump" do
|
5
|
-
|
6
|
-
before(:all) do
|
7
|
-
SchemaPlus::ForeignKeys.setup do |config|
|
8
|
-
config.auto_create = false
|
9
|
-
end
|
10
|
-
ActiveRecord::Migration.suppress_messages do
|
11
|
-
ActiveRecord::Schema.define do
|
12
|
-
connection.tables.each do |table| drop_table table, force: :cascade end
|
13
|
-
|
14
|
-
create_table :users, :force => true do |t|
|
15
|
-
t.string :login
|
16
|
-
t.datetime :deleted_at
|
17
|
-
t.integer :first_post_id, index: { unique: true }
|
18
|
-
end
|
19
|
-
|
20
|
-
create_table :posts, :force => true do |t|
|
21
|
-
t.text :body
|
22
|
-
t.integer :user_id
|
23
|
-
t.integer :first_comment_id
|
24
|
-
t.string :string_no_default
|
25
|
-
t.integer :short_id
|
26
|
-
t.string :str_short
|
27
|
-
t.integer :integer_col
|
28
|
-
t.float :float_col
|
29
|
-
t.decimal :decimal_col
|
30
|
-
t.datetime :datetime_col
|
31
|
-
t.timestamp :timestamp_col
|
32
|
-
t.time :time_col
|
33
|
-
t.date :date_col
|
34
|
-
t.binary :binary_col
|
35
|
-
t.boolean :boolean_col
|
36
|
-
end
|
37
|
-
|
38
|
-
create_table :comments, :force => true do |t|
|
39
|
-
t.text :body
|
40
|
-
t.integer :post_id
|
41
|
-
t.integer :commenter_id
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
class ::User < ActiveRecord::Base ; end
|
46
|
-
class ::Post < ActiveRecord::Base ; end
|
47
|
-
class ::Comment < ActiveRecord::Base ; end
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should include foreign_key definition" do
|
51
|
-
with_foreign_key Post, :user_id, :users, :id do
|
52
|
-
expect(dump_posts).to match(%r{t.integer\s+"user_id".*foreign_key.*users})
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should include foreign_key name" do
|
57
|
-
with_foreign_key Post, :user_id, :users, :id, :name => "yippee" do
|
58
|
-
expect(dump_posts).to match(/user_id.*foreign_key.*users.*name: "yippee"/)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should respect foreign key's primary key" do
|
63
|
-
with_foreign_key Post, :user_id, :users, :first_post_id do
|
64
|
-
expect(dump_posts).to match(%r{t.integer\s+"user_id".*foreign_key.*primary_key: "first_post_id"})
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
it "should include foreign_key exactly once" do
|
70
|
-
with_foreign_key Post, :user_id, :users, :id, :name => "yippee" do
|
71
|
-
expect(dump_posts.scan(/foreign_key.*yippee"/).length).to eq 1
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
xit "should sort foreign_key definitions" do
|
77
|
-
with_foreign_keys Comment, [ [ :post_id, :posts, :id ], [ :commenter_id, :users, :id ]] do
|
78
|
-
expect(dump_schema).to match(/foreign_key.+commenter_id.+foreign_key.+post_id/m)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context "with constraint dependencies" do
|
83
|
-
it "should sort in Posts => Comments direction" do
|
84
|
-
with_foreign_key Comment, :post_id, :posts, :id do
|
85
|
-
expect(dump_schema).to match(%r{create_table "posts".*create_table "comments"}m)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
it "should sort in Comments => Posts direction" do
|
89
|
-
with_foreign_key Post, :first_comment_id, :comments, :id do
|
90
|
-
expect(dump_schema).to match(%r{create_table "comments".*create_table "posts"}m)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
it "should handle regexp in ignore_tables" do
|
95
|
-
with_foreign_key Comment, :post_id, :posts, :id do
|
96
|
-
dump = dump_schema(:ignore => /post/)
|
97
|
-
expect(dump).to match(/create_table "comments"/)
|
98
|
-
expect(dump).not_to match(/create_table "posts"/)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
it "should include foreign_key options" do
|
105
|
-
with_foreign_key Post, :user_id, :users, :id, :on_update => :cascade, :on_delete => :nullify do
|
106
|
-
expect(dump_posts).to match(%q[t.integer\s*"user_id",.*foreign_key: {references: "users", name: "fk_posts_user_id", on_update: :cascade, on_delete: :nullify}])
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
context "with cyclic foreign key constraints", :sqlite3 => :skip do
|
111
|
-
before(:all) do
|
112
|
-
ActiveRecord::Base.connection.add_foreign_key(Comment.table_name, User.table_name, column: :commenter_id)
|
113
|
-
ActiveRecord::Base.connection.add_foreign_key(Comment.table_name, Post.table_name, column: :post_id)
|
114
|
-
ActiveRecord::Base.connection.add_foreign_key(Post.table_name, Comment.table_name, column: :first_comment_id)
|
115
|
-
ActiveRecord::Base.connection.add_foreign_key(Post.table_name, User.table_name, column: :user_id)
|
116
|
-
ActiveRecord::Base.connection.add_foreign_key(User.table_name, Post.table_name, column: :first_post_id)
|
117
|
-
end
|
118
|
-
|
119
|
-
it "should not raise an error" do
|
120
|
-
expect { dump_schema }.to_not raise_error
|
121
|
-
end
|
122
|
-
|
123
|
-
["comments", "posts", "users"].each do |table|
|
124
|
-
it "should dump constraints for table #{table.inspect} after the table definition" do
|
125
|
-
dump = dump_schema.gsub(/#[^\n*]/m, '')
|
126
|
-
expect(dump =~ %r{create_table "#{table}"}).to be < (dump =~ %r{foreign_key.*"#{table}"})
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
["comments", "posts"].each do |table|
|
131
|
-
qtable = table.inspect
|
132
|
-
it "should dump comments for delayed constraint definition referencing table #{qtable}" do
|
133
|
-
expect(dump_schema).to match(%r{# foreign key references #{qtable}.*create_table #{qtable}.*add_foreign_key \S+, #{qtable}}m)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'with complicated schemas' do
|
138
|
-
before(:all) do
|
139
|
-
|
140
|
-
SchemaPlus::ForeignKeys.setup do |config|
|
141
|
-
config.auto_create = false
|
142
|
-
end
|
143
|
-
ActiveRecord::Migration.suppress_messages do
|
144
|
-
ActiveRecord::Schema.define do
|
145
|
-
connection.tables.each do |table| drop_table table, force: :cascade end
|
146
|
-
|
147
|
-
create_table :grade_systems, force: true do |t|
|
148
|
-
t.string :name
|
149
|
-
t.integer :school_id
|
150
|
-
t.integer :parent_id
|
151
|
-
t.integer :profile_id
|
152
|
-
end
|
153
|
-
|
154
|
-
create_table :schools, force: true do |t|
|
155
|
-
t.string :name
|
156
|
-
t.integer :default_grade_system_id
|
157
|
-
end
|
158
|
-
|
159
|
-
create_table :academic_years, force: true do |t|
|
160
|
-
t.string :name
|
161
|
-
t.integer :school_id
|
162
|
-
end
|
163
|
-
|
164
|
-
create_table :buildings, force: true do |t|
|
165
|
-
t.string :name
|
166
|
-
t.integer :school_id
|
167
|
-
end
|
168
|
-
|
169
|
-
create_table :profiles, force: true do |t|
|
170
|
-
t.integer :school_id
|
171
|
-
t.integer :building_id
|
172
|
-
end
|
173
|
-
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
class ::AcademicYear < ActiveRecord::Base ; end
|
178
|
-
class ::Building < ActiveRecord::Base ; end
|
179
|
-
class ::GradeSystem < ActiveRecord::Base ; end
|
180
|
-
class ::Profile < ActiveRecord::Base ; end
|
181
|
-
class ::School < ActiveRecord::Base ; end
|
182
|
-
|
183
|
-
ActiveRecord::Base.connection.add_foreign_key(School.table_name, GradeSystem.table_name, column: :default_grade_system_id)
|
184
|
-
ActiveRecord::Base.connection.add_foreign_key(GradeSystem.table_name, School.table_name, column: :school_id)
|
185
|
-
ActiveRecord::Base.connection.add_foreign_key(GradeSystem.table_name, GradeSystem.table_name, column: :parent_id)
|
186
|
-
ActiveRecord::Base.connection.add_foreign_key(GradeSystem.table_name, Profile.table_name, column: :profile_id)
|
187
|
-
ActiveRecord::Base.connection.add_foreign_key(Profile.table_name, Building.table_name, column: :building_id)
|
188
|
-
ActiveRecord::Base.connection.add_foreign_key(Profile.table_name, School.table_name, column: :school_id)
|
189
|
-
ActiveRecord::Base.connection.add_foreign_key(Building.table_name, School.table_name, column: :school_id)
|
190
|
-
ActiveRecord::Base.connection.add_foreign_key(AcademicYear.table_name, School.table_name, column: :school_id)
|
191
|
-
end
|
192
|
-
|
193
|
-
it "should not raise an error" do
|
194
|
-
expect { dump_schema }.to_not raise_error
|
195
|
-
end
|
196
|
-
|
197
|
-
["buildings", "grade_systems", "profiles", "schools"].each do |table|
|
198
|
-
it "should dump constraints for table #{table.inspect} after the table definition" do
|
199
|
-
expect(dump_schema =~ %r{create_table "#{table}"}).to be < (dump_schema =~ %r{foreign_key.*"#{table}"})
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
protected
|
206
|
-
def to_regexp(string)
|
207
|
-
Regexp.new(Regexp.escape(string))
|
208
|
-
end
|
209
|
-
|
210
|
-
def with_foreign_key(model, columns, referenced_table_name, referenced_columns, options = {}, &block)
|
211
|
-
with_foreign_keys(model, [[columns, referenced_table_name, referenced_columns, options]], &block)
|
212
|
-
end
|
213
|
-
|
214
|
-
def with_foreign_keys(model, columnsets)
|
215
|
-
table_columns = model.columns.reject{|column| column.name == 'id'}
|
216
|
-
ActiveRecord::Migration.suppress_messages do
|
217
|
-
ActiveRecord::Migration.create_table model.table_name, :force => true do |t|
|
218
|
-
table_columns.each do |column|
|
219
|
-
t.column column.name, column.type
|
220
|
-
end
|
221
|
-
columnsets.each do |columns, referenced_table_name, referenced_columns, options|
|
222
|
-
t.foreign_key columns, referenced_table_name, (options||{}).merge(primary_key: referenced_columns)
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
226
|
-
model.reset_column_information
|
227
|
-
begin
|
228
|
-
yield
|
229
|
-
ensure
|
230
|
-
ActiveRecord::Migration.suppress_messages do
|
231
|
-
ActiveRecord::Migration.create_table model.table_name, :force => true do |t|
|
232
|
-
table_columns.each do |column|
|
233
|
-
t.column column.name, column.type
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def determine_foreign_key_name(model, columns, options)
|
241
|
-
name = options[:name]
|
242
|
-
name ||= model.foreign_keys.detect { |fk| fk.from_table == model.table_name.to_s && Array.wrap(fk.column) == Array.wrap(columns).collect(&:to_s) }.name
|
243
|
-
end
|
244
|
-
|
245
|
-
def dump_schema(opts={})
|
246
|
-
stream = StringIO.new
|
247
|
-
ActiveRecord::SchemaDumper.ignore_tables = Array.wrap(opts[:ignore]) || []
|
248
|
-
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
|
249
|
-
stream.string
|
250
|
-
end
|
251
|
-
|
252
|
-
def dump_posts
|
253
|
-
dump_schema(:ignore => %w[users comments])
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ActiveRecord::Schema do
|
4
|
-
|
5
|
-
let(:schema) { ActiveRecord::Schema }
|
6
|
-
|
7
|
-
let(:connection) { ActiveRecord::Base.connection }
|
8
|
-
|
9
|
-
context "defining with auto_index and auto_create" do
|
10
|
-
|
11
|
-
around(:each) do |example|
|
12
|
-
with_auto_index do
|
13
|
-
with_auto_create do
|
14
|
-
example.run
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should pass" do
|
20
|
-
expect { do_schema }.to_not raise_error
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should create only explicity added indexes" do
|
24
|
-
do_schema
|
25
|
-
expected = SchemaDev::Rspec::Helpers.mysql? ? 2 : 1
|
26
|
-
expect(connection.tables.collect { |table| connection.indexes(table) }.flatten.size).to eq(expected)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should create only explicity added foriegn keys" do
|
30
|
-
do_schema
|
31
|
-
expect(connection.tables.collect { |table| connection.foreign_keys(table) }.flatten.size).to eq(2)
|
32
|
-
end
|
33
|
-
|
34
|
-
protected
|
35
|
-
|
36
|
-
def do_schema
|
37
|
-
define_schema do
|
38
|
-
|
39
|
-
create_table :users, :force => true do
|
40
|
-
end
|
41
|
-
|
42
|
-
create_table :colors, :force => true do
|
43
|
-
end
|
44
|
-
|
45
|
-
create_table :shoes, :force => true do
|
46
|
-
end
|
47
|
-
|
48
|
-
create_table :posts, :force => true do |t|
|
49
|
-
t.integer :user_id, :references => :users, :index => true
|
50
|
-
t.integer :shoe_id, :references => :shoes # should not have an index (except mysql)
|
51
|
-
t.integer :color_id # should not have a foreign key nor index
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
it "handles explicit foreign keys" do
|
59
|
-
expect {
|
60
|
-
with_auto_create(false) do
|
61
|
-
define_schema do
|
62
|
-
create_table :users, :force => :cascade do
|
63
|
-
end
|
64
|
-
|
65
|
-
create_table :posts, :force => :cascade do |t|
|
66
|
-
t.integer :user_id
|
67
|
-
t.foreign_key :users
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
}.not_to raise_error
|
72
|
-
expect(connection.foreign_keys("posts").first.to_table).to eq "users"
|
73
|
-
end
|
74
|
-
|
75
|
-
|
76
|
-
protected
|
77
|
-
|
78
|
-
|
79
|
-
def with_auto_index(value = true)
|
80
|
-
old_value = SchemaPlus::ForeignKeys.config.auto_index
|
81
|
-
SchemaPlus::ForeignKeys.config.auto_index = value
|
82
|
-
begin
|
83
|
-
yield
|
84
|
-
ensure
|
85
|
-
SchemaPlus::ForeignKeys.config.auto_index = old_value
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def with_auto_create(value = true)
|
90
|
-
old_value = SchemaPlus::ForeignKeys.config.auto_create
|
91
|
-
SchemaPlus::ForeignKeys.config.auto_create = value
|
92
|
-
begin
|
93
|
-
yield
|
94
|
-
ensure
|
95
|
-
SchemaPlus::ForeignKeys.config.auto_create = old_value
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|