db_leftovers 1.4.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -5
- data/lib/db_leftovers/dsl.rb +1 -5
- data/lib/db_leftovers/foreign_key.rb +9 -4
- data/lib/db_leftovers/mysql_database_interface.rb +1 -1
- data/lib/db_leftovers/postgres_database_interface.rb +1 -1
- data/lib/db_leftovers/version.rb +1 -1
- data/spec/db_leftovers_spec.rb +10 -10
- data/spec/support/shared_db_tests.rb +25 -2
- metadata +2 -2
data/README.md
CHANGED
@@ -5,7 +5,7 @@ Db\_leftovers lets you define indexes, foreign keys, and CHECK constraints for y
|
|
5
5
|
in one place using an easy-to-read DSL,
|
6
6
|
then run a rake task to bring your database up-to-date.
|
7
7
|
Whenever you edit the DSL, you can re-run the rake task and db\_leftovers will alter your database accordingly.
|
8
|
-
This is useful because of the following limitations in vanilla Rails:
|
8
|
+
This is useful because of the following limitations in vanilla Rails (note that very recently Rails has started to add some of these, e.g. `add_foreign_key`):
|
9
9
|
|
10
10
|
* There are no built-in migration methods to create foreign keys or CHECK constraints.
|
11
11
|
* Even if created, foreign keys and CHECK constraints won't appear in your schema.rb.
|
@@ -69,11 +69,15 @@ This ensures that you have an index on the given table and column(s). The `colum
|
|
69
69
|
This ensures that you have a foreign key relating the given tables and columns.
|
70
70
|
All parameters are strings/symbols except `opts`, which is a hash.
|
71
71
|
If you omit the column names, db\_leftovers will infer them based on Rails conventions. (See examples below.)
|
72
|
-
|
72
|
+
Opts is a hash with the following possible keys:
|
73
73
|
|
74
|
-
* `
|
75
|
-
|
76
|
-
* `:
|
74
|
+
* `:name` The name of the foreign key. Defaults to `fk_`*from\_table*`_`*from\_column*`.
|
75
|
+
|
76
|
+
* `:on_delete` Sets the behavior when a row is deleted and other rows reference it. It may have any of these values:
|
77
|
+
|
78
|
+
* `nil` Indicates that attempting to delete the referenced row should fail (the default).
|
79
|
+
* `:set_null` Indicates that the foreign key should be set to null if the referenced row is deleted.
|
80
|
+
* `:cascade` Indicates that the referencing row should be deleted if the referenced row is deleted.
|
77
81
|
|
78
82
|
#### Examples
|
79
83
|
|
data/lib/db_leftovers/dsl.rb
CHANGED
@@ -68,7 +68,7 @@ module DBLeftovers
|
|
68
68
|
to_column = :id
|
69
69
|
end
|
70
70
|
|
71
|
-
add_foreign_key(ForeignKey.new(
|
71
|
+
add_foreign_key(ForeignKey.new(from_table, from_column, to_table, to_column, opts))
|
72
72
|
end
|
73
73
|
|
74
74
|
def check(table_name, constraint_name, check_expression)
|
@@ -237,10 +237,6 @@ module DBLeftovers
|
|
237
237
|
end
|
238
238
|
end
|
239
239
|
|
240
|
-
def name_constraint(from_table, from_column)
|
241
|
-
"fk_#{from_table}_#{from_column}"
|
242
|
-
end
|
243
|
-
|
244
240
|
def get_database_interface
|
245
241
|
db = ActiveRecord::Base.configurations[Rails.env]['adapter']
|
246
242
|
case db
|
@@ -3,17 +3,18 @@ module DBLeftovers
|
|
3
3
|
class ForeignKey
|
4
4
|
attr_accessor :constraint_name, :from_table, :from_column, :to_table, :to_column, :set_null, :cascade
|
5
5
|
|
6
|
-
def initialize(
|
6
|
+
def initialize(from_table, from_column, to_table, to_column, opts={})
|
7
7
|
opts = {
|
8
|
-
:on_delete => nil
|
8
|
+
:on_delete => nil,
|
9
|
+
:name => name_constraint(from_table, from_column)
|
9
10
|
}.merge(opts)
|
10
11
|
opts.keys.each do |k|
|
11
12
|
raise "`:set_null => true` should now be `:on_delete => :set_null`" if k.to_s == 'set_null'
|
12
13
|
raise "`:cascade => true` should now be `:on_delete => :cascade`" if k.to_s == 'cascade'
|
13
|
-
raise "Unknown option: #{k}" unless [:on_delete].include?(k)
|
14
|
+
raise "Unknown option: #{k}" unless [:on_delete, :name].include?(k)
|
14
15
|
end
|
15
16
|
raise "Unknown on_delete option: #{opts[:on_delete]}" unless [nil, :set_null, :cascade].include?(opts[:on_delete])
|
16
|
-
@constraint_name =
|
17
|
+
@constraint_name = opts[:name].to_s
|
17
18
|
@from_table = from_table.to_s
|
18
19
|
@from_column = from_column.to_s
|
19
20
|
@to_table = to_table.to_s
|
@@ -39,6 +40,10 @@ module DBLeftovers
|
|
39
40
|
"<#{@constraint_name}: from #{@from_table}.#{@from_column} to #{@to_table}.#{@to_column} #{if @set_null; "ON DELETE SET NULL "; elsif @cascade; "ON DELETE CASCADE "; else ""; end}>"
|
40
41
|
end
|
41
42
|
|
43
|
+
def name_constraint(from_table, from_column)
|
44
|
+
"fk_#{from_table}_#{from_column}"
|
45
|
+
end
|
46
|
+
|
42
47
|
end
|
43
48
|
|
44
49
|
end
|
@@ -57,7 +57,7 @@ module DBLeftovers
|
|
57
57
|
when 'SET NULL'; :set_null
|
58
58
|
else; raise "Unknown del type: #{del_type}"
|
59
59
|
end
|
60
|
-
ret[constr_name] = ForeignKey.new(
|
60
|
+
ret[constr_name] = ForeignKey.new(from_table, from_column, to_table, to_column, :name => constr_name, :on_delete => del_type)
|
61
61
|
end
|
62
62
|
return ret
|
63
63
|
end
|
@@ -101,7 +101,7 @@ module DBLeftovers
|
|
101
101
|
when 'n'; :set_null
|
102
102
|
else; raise "Unknown del type: #{del_type}"
|
103
103
|
end
|
104
|
-
ret[constr_name] = ForeignKey.new(
|
104
|
+
ret[constr_name] = ForeignKey.new(from_table, from_column, to_table, to_column, :name => constr_name, :on_delete => del_type)
|
105
105
|
end
|
106
106
|
return ret
|
107
107
|
end
|
data/lib/db_leftovers/version.rb
CHANGED
data/spec/db_leftovers_spec.rb
CHANGED
@@ -222,7 +222,7 @@ describe DBLeftovers do
|
|
222
222
|
|
223
223
|
it "should not create foreign keys when they already exist" do
|
224
224
|
@db.starts_with([], [
|
225
|
-
DBLeftovers::ForeignKey.new('
|
225
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id')
|
226
226
|
])
|
227
227
|
DBLeftovers::Definition.define :db_interface => @db do
|
228
228
|
foreign_key :books, :shelf_id, :shelves
|
@@ -234,7 +234,7 @@ describe DBLeftovers do
|
|
234
234
|
|
235
235
|
it "should not create table-prefixed foreign keys when they already exist" do
|
236
236
|
@db.starts_with([], [
|
237
|
-
DBLeftovers::ForeignKey.new('
|
237
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id')
|
238
238
|
])
|
239
239
|
DBLeftovers::Definition.define :db_interface => @db do
|
240
240
|
table :books do
|
@@ -264,8 +264,8 @@ describe DBLeftovers do
|
|
264
264
|
|
265
265
|
it "should drop foreign keys when they are removed from the definition" do
|
266
266
|
@db.starts_with([], [
|
267
|
-
DBLeftovers::ForeignKey.new('
|
268
|
-
DBLeftovers::ForeignKey.new('
|
267
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id'),
|
268
|
+
DBLeftovers::ForeignKey.new('books', 'author_id', 'authors', 'id')
|
269
269
|
])
|
270
270
|
DBLeftovers::Definition.define :db_interface => @db do
|
271
271
|
foreign_key :books, :shelf_id, :shelves
|
@@ -280,8 +280,8 @@ describe DBLeftovers do
|
|
280
280
|
|
281
281
|
it "should create foreign keys when they have been redefined" do
|
282
282
|
@db.starts_with([], [
|
283
|
-
DBLeftovers::ForeignKey.new('
|
284
|
-
DBLeftovers::ForeignKey.new('
|
283
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id'),
|
284
|
+
DBLeftovers::ForeignKey.new('books', 'author_id', 'authors', 'id')
|
285
285
|
])
|
286
286
|
DBLeftovers::Definition.define :db_interface => @db do
|
287
287
|
table :books do
|
@@ -463,8 +463,8 @@ describe DBLeftovers do
|
|
463
463
|
@db.starts_with([
|
464
464
|
DBLeftovers::Index.new(:books, :shelf_id),
|
465
465
|
], [
|
466
|
-
DBLeftovers::ForeignKey.new('
|
467
|
-
DBLeftovers::ForeignKey.new('
|
466
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id'),
|
467
|
+
DBLeftovers::ForeignKey.new('books', 'author_id', 'authors', 'id')
|
468
468
|
], [
|
469
469
|
DBLeftovers::Constraint.new(:books_have_positive_pages, :books, 'pages_count > 0')
|
470
470
|
])
|
@@ -479,8 +479,8 @@ describe DBLeftovers do
|
|
479
479
|
DBLeftovers::Index.new(:books, :shelf_id),
|
480
480
|
DBLeftovers::Index.new(:authors, :last_name),
|
481
481
|
], [
|
482
|
-
DBLeftovers::ForeignKey.new('
|
483
|
-
DBLeftovers::ForeignKey.new('
|
482
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id'),
|
483
|
+
DBLeftovers::ForeignKey.new('books', 'author_id', 'authors', 'id')
|
484
484
|
], [
|
485
485
|
DBLeftovers::Constraint.new(:books_have_positive_pages, :books, 'pages_count > 0')
|
486
486
|
])
|
@@ -117,8 +117,8 @@ shared_examples_for "DatabaseInterface" do
|
|
117
117
|
|
118
118
|
it "should drop foreign keys when they are removed from the definition" do
|
119
119
|
starts_with(@db, [], [
|
120
|
-
DBLeftovers::ForeignKey.new('
|
121
|
-
DBLeftovers::ForeignKey.new('
|
120
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id'),
|
121
|
+
DBLeftovers::ForeignKey.new('books', 'author_id', 'authors', 'id')
|
122
122
|
])
|
123
123
|
DBLeftovers::Definition.define :db_interface => @db do
|
124
124
|
foreign_key :books, :shelf_id, :shelves
|
@@ -148,5 +148,28 @@ shared_examples_for "DatabaseInterface" do
|
|
148
148
|
@db.lookup_all_indexes.size.should == 0
|
149
149
|
end
|
150
150
|
|
151
|
+
|
152
|
+
it "should create foreign keys with a custom name" do
|
153
|
+
DBLeftovers::Definition.define :db_interface => @db do
|
154
|
+
foreign_key :books, :shelf_id, :shelves, :name => "fk_where_it_is"
|
155
|
+
foreign_key :books, :publisher_id, :publishers, :id, :on_delete => :set_null, :name => "fk_who_published_it"
|
156
|
+
foreign_key :books, :author_id, :authors, :id, :on_delete => :cascade, :name => "fk_who_wrote_it"
|
157
|
+
end
|
158
|
+
@db.lookup_all_foreign_keys.size.should == 3
|
159
|
+
@db.lookup_all_foreign_keys.keys.sort.should == ['fk_where_it_is', 'fk_who_published_it', 'fk_who_wrote_it']
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
it "should drop foreign keys when they are removed from the definition" do
|
164
|
+
starts_with(@db, [], [
|
165
|
+
DBLeftovers::ForeignKey.new('books', 'shelf_id', 'shelves', 'id', :name => "fk_where_it_is"),
|
166
|
+
DBLeftovers::ForeignKey.new('books', 'author_id', 'authors', 'id', :name => "fk_who_wrote_it")
|
167
|
+
])
|
168
|
+
DBLeftovers::Definition.define :db_interface => @db do
|
169
|
+
foreign_key :books, :shelf_id, :shelves, :name => "fk_where_it_is"
|
170
|
+
end
|
171
|
+
@db.lookup_all_foreign_keys.size.should == 1
|
172
|
+
end
|
173
|
+
|
151
174
|
|
152
175
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: db_leftovers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -112,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
112
|
version: '0'
|
113
113
|
segments:
|
114
114
|
- 0
|
115
|
-
hash:
|
115
|
+
hash: -363906017218431327
|
116
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
117
|
none: false
|
118
118
|
requirements:
|