db_leftovers 0.8.0 → 0.9.1
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.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:
|