db_leftovers 1.4.2 → 1.5.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.
- 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:
|