db_leftovers 0.8.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.html +11 -4
- data/README.md +10 -4
- data/VERSION +1 -1
- data/db_leftovers.gemspec +1 -1
- data/lib/db_leftovers/database_interface.rb +3 -2
- data/lib/db_leftovers/dsl.rb +44 -5
- data/lib/db_leftovers/table_dsl.rb +1 -1
- data/spec/db_leftovers_spec.rb +36 -0
- metadata +2 -2
data/README.html
CHANGED
@@ -31,11 +31,11 @@ index :books, [:publisher_id, :published_at]
|
|
31
31
|
index :books, :isbn, :unique => true
|
32
32
|
</code></pre>
|
33
33
|
|
34
|
-
<h3>foreign_key(from_table, from_column, to_table, [to_column, [opts]
|
34
|
+
<h3>foreign_key(from_table, [from_column], to_table, [to_column], [opts])</h3>
|
35
35
|
|
36
36
|
<p>This ensures that you have a foreign key relating the given tables and columns.
|
37
37
|
All parameters are strings/symbols except <code>opts</code>, which is a hash.
|
38
|
-
If you
|
38
|
+
If you omit the column names, db_leftovers will infer them based on Rails conventions. (See examples below.)
|
39
39
|
The only option that is supported is <code>:on_delete</code>, which may have any of these values:</p>
|
40
40
|
|
41
41
|
<ul>
|
@@ -47,10 +47,17 @@ The only option that is supported is <code>:on_delete</code>, which may have any
|
|
47
47
|
<h4>Examples</h4>
|
48
48
|
|
49
49
|
<pre><code>foreign_key :books, :author_id, :authors, :id
|
50
|
-
foreign_key :books, :publisher_id, :publishers
|
51
50
|
foreign_key :pages, :book_id, :books, :id, :on_delete => :cascade
|
52
51
|
</code></pre>
|
53
52
|
|
53
|
+
<p>With implicit column names:</p>
|
54
|
+
|
55
|
+
<pre><code>foreign_key :books, :authors
|
56
|
+
foreign_key :books, :authors, :on_delete => :cascade
|
57
|
+
foreign_key :books, :co_author_id, :authors
|
58
|
+
foreign_key :books, :co_author_id, :authors, :on_delete => :cascade
|
59
|
+
</code></pre>
|
60
|
+
|
54
61
|
<h3>check(constraint_name, on_table, expression)</h3>
|
55
62
|
|
56
63
|
<p>This ensures that you have a CHECK constraint on the given table with the given name and expression.
|
@@ -63,7 +70,7 @@ All parameters are strings or symbols.</p>
|
|
63
70
|
|
64
71
|
<h3>table(table_name, &block)</h3>
|
65
72
|
|
66
|
-
<p>The <code>table</code> call is just a convenience so you can group all a table's indexes
|
73
|
+
<p>The <code>table</code> call is just a convenience so you can group all a table's indexes etcetera together and not keep repeating the table name. You use it like this:</p>
|
67
74
|
|
68
75
|
<pre><code>table :books do
|
69
76
|
index :author_id
|
data/README.md
CHANGED
@@ -32,11 +32,11 @@ This ensures that you have an index on the given table and column(s). The `colum
|
|
32
32
|
index :books, [:publisher_id, :published_at]
|
33
33
|
index :books, :isbn, :unique => true
|
34
34
|
|
35
|
-
### foreign\_key(from\_table, from\_column, to\_table, [to\_column, [opts]
|
35
|
+
### foreign\_key(from\_table, [from\_column], to\_table, [to\_column], [opts])
|
36
36
|
|
37
37
|
This ensures that you have a foreign key relating the given tables and columns.
|
38
38
|
All parameters are strings/symbols except `opts`, which is a hash.
|
39
|
-
If you
|
39
|
+
If you omit the column names, db\_leftovers will infer them based on Rails conventions. (See examples below.)
|
40
40
|
The only option that is supported is `:on_delete`, which may have any of these values:
|
41
41
|
|
42
42
|
* `nil` Indicates that attempting to delete the referenced row should fail (the default).
|
@@ -46,9 +46,15 @@ The only option that is supported is `:on_delete`, which may have any of these v
|
|
46
46
|
#### Examples
|
47
47
|
|
48
48
|
foreign_key :books, :author_id, :authors, :id
|
49
|
-
foreign_key :books, :publisher_id, :publishers
|
50
49
|
foreign_key :pages, :book_id, :books, :id, :on_delete => :cascade
|
51
50
|
|
51
|
+
With implicit column names:
|
52
|
+
|
53
|
+
foreign_key :books, :authors
|
54
|
+
foreign_key :books, :authors, :on_delete => :cascade
|
55
|
+
foreign_key :books, :co_author_id, :authors
|
56
|
+
foreign_key :books, :co_author_id, :authors, :on_delete => :cascade
|
57
|
+
|
52
58
|
### check(constraint\_name, on\_table, expression)
|
53
59
|
|
54
60
|
This ensures that you have a CHECK constraint on the given table with the given name and expression.
|
@@ -60,7 +66,7 @@ All parameters are strings or symbols.
|
|
60
66
|
|
61
67
|
### table(table\_name, &block)
|
62
68
|
|
63
|
-
The `table` call is just a convenience so you can group all a table's indexes
|
69
|
+
The `table` call is just a convenience so you can group all a table's indexes etcetera together and not keep repeating the table name. You use it like this:
|
64
70
|
|
65
71
|
table :books do
|
66
72
|
index :author_id
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.9.1
|
data/db_leftovers.gemspec
CHANGED
@@ -101,7 +101,8 @@ module DBLeftovers
|
|
101
101
|
ret = {}
|
102
102
|
sql = <<-EOQ
|
103
103
|
SELECT c.conname,
|
104
|
-
t.relname
|
104
|
+
t.relname,
|
105
|
+
pg_get_expr(c.conbin, c.conrelid)
|
105
106
|
FROM pg_catalog.pg_constraint c,
|
106
107
|
pg_catalog.pg_class t,
|
107
108
|
pg_catalog.pg_namespace n
|
@@ -182,7 +183,7 @@ module DBLeftovers
|
|
182
183
|
end
|
183
184
|
|
184
185
|
def remove_outer_parens(str)
|
185
|
-
str.gsub(/^\((.*)\)$/, '\1')
|
186
|
+
str ? str.gsub(/^\((.*)\)$/, '\1') : nil
|
186
187
|
end
|
187
188
|
|
188
189
|
|
data/lib/db_leftovers/dsl.rb
CHANGED
@@ -38,7 +38,30 @@ module DBLeftovers
|
|
38
38
|
add_index(Index.new(table_name, column_names, opts))
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
# foreign_key(from_table, [from_column], to_table, [to_column], [opts]):
|
42
|
+
# foreign_key(:books, :publishers) -> foreign_key(:books, nil, :publishers, nil)
|
43
|
+
# foreign_key(:books, :co_author_id, :authors) -> foreign_key(:books, :co_author_id, :authors, nil)
|
44
|
+
# foreign_key(:books, :publishers, opts) -> foreign_key(:books, nil, :publishers, nil, opts)
|
45
|
+
# foreign_key(:books, :co_author_id, :authors, opts) -> foreign_key(:books, :co_author_id, :authors, nil, opts)
|
46
|
+
def foreign_key(from_table, from_column=nil, to_table=nil, to_column=nil, opts={})
|
47
|
+
# First get the options hash into the right place:
|
48
|
+
if to_column.class == Hash
|
49
|
+
opts = to_column
|
50
|
+
to_column = nil
|
51
|
+
elsif to_table.class == Hash
|
52
|
+
opts = to_table
|
53
|
+
to_table = to_column = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
# Sort out implicit arguments:
|
57
|
+
if from_column and not to_table and not to_column
|
58
|
+
to_table = from_column
|
59
|
+
from_column = "#{to_table.to_s.singularize}_id"
|
60
|
+
to_column = :id
|
61
|
+
elsif from_column and to_table and not to_column
|
62
|
+
to_column = :id
|
63
|
+
end
|
64
|
+
|
42
65
|
add_foreign_key(ForeignKey.new(name_constraint(from_table, from_column), from_table, from_column, to_table, to_column, opts))
|
43
66
|
end
|
44
67
|
|
@@ -57,10 +80,22 @@ module DBLeftovers
|
|
57
80
|
when STATUS_CHANGED
|
58
81
|
@db.execute_drop_index(idx.table_name, idx.index_name)
|
59
82
|
@db.execute_add_index(idx)
|
60
|
-
|
83
|
+
if idx.where_clause
|
84
|
+
# NB: This is O(n*m) where n is your indexes and m is your indexes with WHERE clauses.
|
85
|
+
# But it's hard to believe it matters:
|
86
|
+
new_idx = @db.lookup_all_indexes[truncate_index_name(idx.index_name)]
|
87
|
+
puts "Dropped & re-created index: #{idx.index_name} on #{idx.table_name} WHERE #{new_idx.where_clause}"
|
88
|
+
else
|
89
|
+
puts "Dropped & re-created index: #{idx.index_name} on #{idx.table_name}"
|
90
|
+
end
|
61
91
|
when STATUS_NEW
|
62
92
|
@db.execute_add_index(idx)
|
63
|
-
|
93
|
+
if idx.where_clause
|
94
|
+
new_idx = @db.lookup_all_indexes[truncate_index_name(idx.index_name)]
|
95
|
+
puts "Created index: #{idx.index_name} on #{idx.table_name} WHERE #{new_idx.where_clause}"
|
96
|
+
else
|
97
|
+
puts "Created index: #{idx.index_name} on #{idx.table_name}"
|
98
|
+
end
|
64
99
|
end
|
65
100
|
@new_indexes[truncate_index_name(idx.index_name)] = table_name
|
66
101
|
end
|
@@ -114,10 +149,14 @@ module DBLeftovers
|
|
114
149
|
when STATUS_CHANGED
|
115
150
|
@db.execute_drop_constraint(chk.constraint_name, chk.on_table)
|
116
151
|
@db.execute_add_constraint(chk)
|
117
|
-
|
152
|
+
# NB: This is O(n^2) where n is your check constraints.
|
153
|
+
# But it's hard to believe it matters:
|
154
|
+
new_chk = @db.lookup_all_constraints[chk.constraint_name]
|
155
|
+
puts "Dropped & re-created CHECK constraint: #{chk.constraint_name} on #{chk.on_table} as #{new_chk.check}"
|
118
156
|
when STATUS_NEW
|
119
157
|
@db.execute_add_constraint(chk)
|
120
|
-
|
158
|
+
new_chk = @db.lookup_all_constraints[chk.constraint_name]
|
159
|
+
puts "Created CHECK constraint: #{chk.constraint_name} on #{chk.on_table} as #{new_chk.check}"
|
121
160
|
end
|
122
161
|
@new_constraints[chk.constraint_name] = chk
|
123
162
|
end
|
@@ -14,7 +14,7 @@ module DBLeftovers
|
|
14
14
|
@dsl.index(@table_name, column_names, opts)
|
15
15
|
end
|
16
16
|
|
17
|
-
def foreign_key(from_column, to_table, to_column=
|
17
|
+
def foreign_key(from_column=nil, to_table=nil, to_column=nil, opts={})
|
18
18
|
@dsl.foreign_key(@table_name, from_column, to_table, to_column, opts)
|
19
19
|
end
|
20
20
|
|
data/spec/db_leftovers_spec.rb
CHANGED
@@ -187,7 +187,43 @@ describe DBLeftovers do
|
|
187
187
|
EOQ
|
188
188
|
end
|
189
189
|
|
190
|
+
it "should create foreign keys with optional params inferred" do
|
191
|
+
DBLeftovers::DatabaseInterface.starts_with
|
192
|
+
DBLeftovers::Definition.define do
|
193
|
+
foreign_key :books, :shelves
|
194
|
+
foreign_key :books, :publishers, :on_delete => :set_null
|
195
|
+
foreign_key :books, :publication_country_id, :countries
|
196
|
+
foreign_key :books, :co_author_id, :authors, :on_delete => :cascade
|
197
|
+
end
|
198
|
+
DBLeftovers::DatabaseInterface.sqls.should have(4).items
|
199
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
200
|
+
ALTER TABLE books ADD CONSTRAINT fk_books_shelf_id FOREIGN KEY (shelf_id) REFERENCES shelves (id)
|
201
|
+
EOQ
|
202
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
203
|
+
ALTER TABLE books ADD CONSTRAINT fk_books_publisher_id FOREIGN KEY (publisher_id) REFERENCES publishers (id) ON DELETE SET NULL
|
204
|
+
EOQ
|
205
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
206
|
+
ALTER TABLE books ADD CONSTRAINT fk_books_publication_country_id
|
207
|
+
FOREIGN KEY (publication_country_id) REFERENCES countries (id)
|
208
|
+
EOQ
|
209
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
210
|
+
ALTER TABLE books ADD CONSTRAINT fk_books_co_author_id
|
211
|
+
FOREIGN KEY (co_author_id) REFERENCES authors (id) ON DELETE CASCADE
|
212
|
+
EOQ
|
213
|
+
end
|
190
214
|
|
215
|
+
it "should create foreign keys with optional params inferred and table block" do
|
216
|
+
DBLeftovers::DatabaseInterface.starts_with
|
217
|
+
DBLeftovers::Definition.define do
|
218
|
+
table :books do
|
219
|
+
foreign_key :shelves
|
220
|
+
foreign_key :publishers
|
221
|
+
foreign_key :publication_country_id, :countries
|
222
|
+
foreign_key :co_author_id, :authors, :on_delete => :cascade
|
223
|
+
end
|
224
|
+
end
|
225
|
+
DBLeftovers::DatabaseInterface.sqls.should have(4).items
|
226
|
+
end
|
191
227
|
|
192
228
|
it "should not create indexes when they already exist" do
|
193
229
|
DBLeftovers::DatabaseInterface.starts_with([
|
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: 0.
|
4
|
+
version: 0.9.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -139,7 +139,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
139
|
version: '0'
|
140
140
|
segments:
|
141
141
|
- 0
|
142
|
-
hash:
|
142
|
+
hash: 712708189
|
143
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
144
|
none: false
|
145
145
|
requirements:
|