db_leftovers 0.3.0 → 0.4.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/.document +0 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +10 -10
- data/LICENSE.txt +0 -0
- data/README.html +0 -0
- data/README.md +2 -2
- data/Rakefile +0 -0
- data/TODO +5 -0
- data/VERSION +1 -1
- data/db_leftovers.gemspec +10 -9
- data/lib/db_leftovers.rb +1 -0
- data/lib/db_leftovers/constraint.rb +13 -0
- data/lib/db_leftovers/database_interface.rb +28 -2
- data/lib/db_leftovers/definition.rb +3 -1
- data/lib/db_leftovers/dsl.rb +40 -0
- data/lib/db_leftovers/foreign_key.rb +0 -0
- data/lib/db_leftovers/index.rb +0 -0
- data/lib/db_leftovers/table_dsl.rb +4 -0
- data/lib/tasks/leftovers.rake +9 -3
- data/spec/db_leftovers_spec.rb +167 -2
- data/spec/spec_helper.rb +0 -0
- metadata +43 -17
data/.document
CHANGED
File without changes
|
data/Gemfile
CHANGED
@@ -11,8 +11,9 @@ gem 'rails', '>= 3.0.0'
|
|
11
11
|
# Add dependencies to develop your gem here.
|
12
12
|
# Include everything needed to run rake, tests, features, etc.
|
13
13
|
group :development do
|
14
|
-
gem "rspec", "~> 2.
|
15
|
-
gem "bundler"
|
14
|
+
gem "rspec", "~> 2.4.0"
|
15
|
+
gem "bundler"
|
16
16
|
gem "jeweler", "~> 1.6.4"
|
17
17
|
gem "rcov", ">= 0"
|
18
18
|
end
|
19
|
+
|
data/Gemfile.lock
CHANGED
@@ -76,18 +76,18 @@ GEM
|
|
76
76
|
rcov (0.9.11)
|
77
77
|
rdoc (3.12)
|
78
78
|
json (~> 1.4)
|
79
|
-
rspec (2.
|
80
|
-
rspec-core (~> 2.
|
81
|
-
rspec-expectations (~> 2.
|
82
|
-
rspec-mocks (~> 2.
|
83
|
-
rspec-core (2.
|
84
|
-
rspec-expectations (2.
|
79
|
+
rspec (2.4.0)
|
80
|
+
rspec-core (~> 2.4.0)
|
81
|
+
rspec-expectations (~> 2.4.0)
|
82
|
+
rspec-mocks (~> 2.4.0)
|
83
|
+
rspec-core (2.4.0)
|
84
|
+
rspec-expectations (2.4.0)
|
85
85
|
diff-lcs (~> 1.1.2)
|
86
|
-
rspec-mocks (2.
|
86
|
+
rspec-mocks (2.4.0)
|
87
87
|
sprockets (2.0.3)
|
88
88
|
hike (~> 1.2)
|
89
89
|
rack (~> 1.0)
|
90
|
-
tilt (
|
90
|
+
tilt (~> 1.1, != 1.3.0)
|
91
91
|
thor (0.14.6)
|
92
92
|
tilt (1.3.3)
|
93
93
|
treetop (1.4.10)
|
@@ -99,8 +99,8 @@ PLATFORMS
|
|
99
99
|
ruby
|
100
100
|
|
101
101
|
DEPENDENCIES
|
102
|
-
bundler
|
102
|
+
bundler
|
103
103
|
jeweler (~> 1.6.4)
|
104
104
|
rails (>= 3.0.0)
|
105
105
|
rcov
|
106
|
-
rspec (~> 2.
|
106
|
+
rspec (~> 2.4.0)
|
data/LICENSE.txt
CHANGED
File without changes
|
data/README.html
CHANGED
File without changes
|
data/README.md
CHANGED
data/Rakefile
CHANGED
File without changes
|
data/TODO
CHANGED
@@ -1,3 +1,8 @@
|
|
1
1
|
- Write the README
|
2
2
|
- Support altering index and foreign keys if their definition changes
|
3
3
|
- don't show "{index,fk} already exists" unless you set the verbosity higher
|
4
|
+
|
5
|
+
- Use Sequel to introspect databases for their indexes, to get easy support for non-Postgres databases.
|
6
|
+
- BUT: Sequel can't return partial indexes (i.e. indexes created with a WHERE clause), and using those kind of indexes is a major feature for db_leftovers. So this will have to wait until I can get a patch accepted to let at least the Postgres Sequel adapter optionally query for those type of indexes.
|
7
|
+
|
8
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/db_leftovers.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "db_leftovers"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Paul A. Jungwirth"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-09-27"
|
13
13
|
s.description = " Define indexes and foreign keys for your Rails app\n in one place using an easy-to-read DSL,\n then run a rake task to bring your database up-to-date.\n"
|
14
14
|
s.email = "pj@illuminatedcomputing.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
"VERSION",
|
29
29
|
"db_leftovers.gemspec",
|
30
30
|
"lib/db_leftovers.rb",
|
31
|
+
"lib/db_leftovers/constraint.rb",
|
31
32
|
"lib/db_leftovers/database_interface.rb",
|
32
33
|
"lib/db_leftovers/definition.rb",
|
33
34
|
"lib/db_leftovers/dsl.rb",
|
@@ -41,7 +42,7 @@ Gem::Specification.new do |s|
|
|
41
42
|
s.homepage = "http://github.com/pjungwir/db_leftovers"
|
42
43
|
s.licenses = ["MIT"]
|
43
44
|
s.require_paths = ["lib"]
|
44
|
-
s.rubygems_version = "1.8.
|
45
|
+
s.rubygems_version = "1.8.24"
|
45
46
|
s.summary = "Used to define indexes and foreign keys for your Rails app"
|
46
47
|
|
47
48
|
if s.respond_to? :specification_version then
|
@@ -49,21 +50,21 @@ Gem::Specification.new do |s|
|
|
49
50
|
|
50
51
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
51
52
|
s.add_runtime_dependency(%q<rails>, [">= 3.0.0"])
|
52
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.
|
53
|
-
s.add_development_dependency(%q<bundler>, ["
|
53
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.4.0"])
|
54
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
54
55
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
55
56
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
56
57
|
else
|
57
58
|
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
58
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
59
|
-
s.add_dependency(%q<bundler>, ["
|
59
|
+
s.add_dependency(%q<rspec>, ["~> 2.4.0"])
|
60
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
60
61
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
61
62
|
s.add_dependency(%q<rcov>, [">= 0"])
|
62
63
|
end
|
63
64
|
else
|
64
65
|
s.add_dependency(%q<rails>, [">= 3.0.0"])
|
65
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
66
|
-
s.add_dependency(%q<bundler>, ["
|
66
|
+
s.add_dependency(%q<rspec>, ["~> 2.4.0"])
|
67
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
67
68
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
68
69
|
s.add_dependency(%q<rcov>, [">= 0"])
|
69
70
|
end
|
data/lib/db_leftovers.rb
CHANGED
@@ -0,0 +1,13 @@
|
|
1
|
+
module DBLeftovers
|
2
|
+
|
3
|
+
class Constraint
|
4
|
+
attr_accessor :constraint_name, :on_table, :check
|
5
|
+
|
6
|
+
def initialize(constraint_name, on_table, check)
|
7
|
+
@constraint_name = constraint_name.to_s
|
8
|
+
@on_table = on_table.to_s
|
9
|
+
@check = check
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -44,6 +44,22 @@ module DBLeftovers
|
|
44
44
|
return ret
|
45
45
|
end
|
46
46
|
|
47
|
+
def lookup_all_constraints
|
48
|
+
ret = {}
|
49
|
+
sql = <<-EOQ
|
50
|
+
SELECT t.constraint_name, t.table_name
|
51
|
+
FROM information_schema.table_constraints t
|
52
|
+
WHERE t.constraint_type = 'CHECK'
|
53
|
+
AND EXISTS (SELECT 1
|
54
|
+
FROM information_schema.constraint_column_usage c
|
55
|
+
WHERE t.constraint_name = c.constraint_name)
|
56
|
+
EOQ
|
57
|
+
ActiveRecord::Base.connection.select_rows(sql).each do |constr_name, on_table|
|
58
|
+
ret[constr_name] = Constraint.new(constr_name, on_table, nil)
|
59
|
+
end
|
60
|
+
return ret
|
61
|
+
end
|
62
|
+
|
47
63
|
def execute_add_index(idx)
|
48
64
|
unique = idx.unique? ? 'UNIQUE' : ''
|
49
65
|
where = idx.where_clause.present? ? "WHERE #{idx.where_clause}" : ''
|
@@ -75,8 +91,18 @@ module DBLeftovers
|
|
75
91
|
end
|
76
92
|
|
77
93
|
def execute_drop_foreign_key(constraint_name, from_table, from_column)
|
78
|
-
execute_sql %{ALTER TABLE #{from_table}
|
79
|
-
|
94
|
+
execute_sql %{ALTER TABLE #{from_table} DROP CONSTRAINT #{constraint_name}}
|
95
|
+
end
|
96
|
+
|
97
|
+
def execute_add_constraint(chk)
|
98
|
+
sql = <<-EOQ
|
99
|
+
ALTER TABLE #{chk.on_table} ADD CONSTRAINT #{chk.constraint_name} CHECK (#{chk.check})
|
100
|
+
EOQ
|
101
|
+
execute_sql sql
|
102
|
+
end
|
103
|
+
|
104
|
+
def execute_drop_constraint(constraint_name, on_table)
|
105
|
+
execute_sql %{ALTER TABLE #{on_table} DROP CONSTRAINT #{constraint_name}}
|
80
106
|
end
|
81
107
|
|
82
108
|
def execute_sql(sql)
|
@@ -4,12 +4,14 @@ module DBLeftovers
|
|
4
4
|
def self.define(opts={}, &block)
|
5
5
|
opts = {
|
6
6
|
:do_indexes => true,
|
7
|
-
:do_foreign_keys => true
|
7
|
+
:do_foreign_keys => true,
|
8
|
+
:do_constraints => true
|
8
9
|
}.merge(opts)
|
9
10
|
dsl = DSL.new
|
10
11
|
dsl.define(&block)
|
11
12
|
dsl.record_indexes if opts[:do_indexes]
|
12
13
|
dsl.record_foreign_keys if opts[:do_foreign_keys]
|
14
|
+
dsl.record_constraints if opts[:do_constraints]
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
data/lib/db_leftovers/dsl.rb
CHANGED
@@ -10,6 +10,10 @@ module DBLeftovers
|
|
10
10
|
@foreign_keys_by_table = {} # Set from the DSL
|
11
11
|
@old_foreign_keys = @db.lookup_all_foreign_keys
|
12
12
|
@new_foreign_keys = {}
|
13
|
+
|
14
|
+
@constraints_by_table = {} # Set from the DSL
|
15
|
+
@old_constraints = @db.lookup_all_constraints
|
16
|
+
@new_constraints = {}
|
13
17
|
end
|
14
18
|
|
15
19
|
def define(&block)
|
@@ -31,6 +35,10 @@ module DBLeftovers
|
|
31
35
|
add_foreign_key(ForeignKey.new(name_constraint(from_table, from_column), from_table, from_column, to_table, to_column, opts))
|
32
36
|
end
|
33
37
|
|
38
|
+
def check(table_name, constraint_name, check_expression)
|
39
|
+
add_constraint(Constraint.new(constraint_name, table_name, check_expression))
|
40
|
+
end
|
41
|
+
|
34
42
|
def record_indexes
|
35
43
|
# First create any new indexes:
|
36
44
|
@indexes_by_table.each do |table_name, indexes|
|
@@ -79,6 +87,29 @@ module DBLeftovers
|
|
79
87
|
end
|
80
88
|
end
|
81
89
|
|
90
|
+
def record_constraints
|
91
|
+
# First create any new constraints:
|
92
|
+
@constraints_by_table.each do |table_name, chks|
|
93
|
+
chks.each do |chk|
|
94
|
+
if constraint_exists?(chk)
|
95
|
+
puts "Constraint already exists: #{chk.constraint_name} on #{chk.on_table}"
|
96
|
+
else
|
97
|
+
@db.execute_add_constraint(chk)
|
98
|
+
puts "Created CHECK constraint: #{chk.constraint_name} on #{chk.on_table}"
|
99
|
+
end
|
100
|
+
@new_constraints[chk.constraint_name] = chk
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Now drop any old constraints that are no longer in the definition file:
|
105
|
+
@old_constraints.each do |constraint_name, chk|
|
106
|
+
if not @new_constraints[constraint_name]
|
107
|
+
@db.execute_drop_constraint(constraint_name, chk.on_table)
|
108
|
+
puts "Dropped CHECK constraint: #{constraint_name} on #{chk.on_table}"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
82
113
|
private
|
83
114
|
|
84
115
|
def add_index(idx)
|
@@ -91,6 +122,11 @@ module DBLeftovers
|
|
91
122
|
t << fk
|
92
123
|
end
|
93
124
|
|
125
|
+
def add_constraint(chk)
|
126
|
+
t = (@constraints_by_table[chk.on_table] ||= [])
|
127
|
+
t << chk
|
128
|
+
end
|
129
|
+
|
94
130
|
def truncate_index_name(index_name)
|
95
131
|
index_name[0,63]
|
96
132
|
end
|
@@ -103,6 +139,10 @@ module DBLeftovers
|
|
103
139
|
@old_foreign_keys[fk.constraint_name]
|
104
140
|
end
|
105
141
|
|
142
|
+
def constraint_exists?(chk)
|
143
|
+
@old_constraints[chk.constraint_name]
|
144
|
+
end
|
145
|
+
|
106
146
|
def name_constraint(from_table, from_column)
|
107
147
|
"fk_#{from_table}_#{from_column}"
|
108
148
|
end
|
File without changes
|
data/lib/db_leftovers/index.rb
CHANGED
File without changes
|
@@ -17,6 +17,10 @@ module DBLeftovers
|
|
17
17
|
def foreign_key(from_column, to_table, to_column='id', opts={})
|
18
18
|
@dsl.foreign_key(@table_name, from_column, to_table, to_column, opts)
|
19
19
|
end
|
20
|
+
|
21
|
+
def check(constraint_name, check_expression)
|
22
|
+
@dsl.check(@table_name, constraint_name, check_expression)
|
23
|
+
end
|
20
24
|
end
|
21
25
|
|
22
26
|
end
|
data/lib/tasks/leftovers.rake
CHANGED
@@ -1,19 +1,25 @@
|
|
1
1
|
namespace :db do
|
2
2
|
|
3
|
-
desc "Set up indexes
|
3
|
+
desc "Set up indexes, foreign keys, and constraints"
|
4
4
|
task :leftovers, [] => [:environment] do
|
5
5
|
load File.join(::Rails.root.to_s, 'config', 'db_leftovers.rb')
|
6
6
|
end
|
7
7
|
|
8
8
|
desc "Drop all the indexes"
|
9
9
|
task :drop_indexes, [] => [:environment] do
|
10
|
-
DBLeftovers::Definition.define(:do_indexes => true, :do_foreign_keys => false) do
|
10
|
+
DBLeftovers::Definition.define(:do_indexes => true, :do_foreign_keys => false, :do_constraints => false) do
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
desc "Drop all the foreign keys"
|
15
15
|
task :drop_foreign_keys, [] => [:environment] do
|
16
|
-
DBLeftovers::Definition.define(:do_indexes => false, :do_foreign_keys => true) do
|
16
|
+
DBLeftovers::Definition.define(:do_indexes => false, :do_foreign_keys => true, :do_constraints => false) do
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Drop all the constraints"
|
21
|
+
task :drop_constraints, [] => [:environment] do
|
22
|
+
DBLeftovers::Definition.define(:do_indexes => false, :do_foreign_keys => false, :do_constraints => true) do
|
17
23
|
end
|
18
24
|
end
|
19
25
|
|
data/spec/db_leftovers_spec.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'rails'
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
3
|
|
4
|
-
DBLeftovers::DatabaseInterface.class_eval do
|
4
|
+
# DBLeftovers::DatabaseInterface.class_eval do
|
5
|
+
class DBLeftovers::DatabaseInterface
|
5
6
|
|
6
7
|
def initialize
|
7
8
|
@@sqls = []
|
@@ -23,10 +24,11 @@ DBLeftovers::DatabaseInterface.class_eval do
|
|
23
24
|
)
|
24
25
|
end
|
25
26
|
|
26
|
-
def self.starts_with(indexes, foreign_keys)
|
27
|
+
def self.starts_with(indexes, foreign_keys, constraints={})
|
27
28
|
# Convert symbols to strings:
|
28
29
|
@@indexes = indexes.inject({}) do |h, (k, v)| h[k.to_s] = v; h end
|
29
30
|
@@foreign_keys = foreign_keys.inject({}) do |h, (k, v)| h[k.to_s] = v; h end
|
31
|
+
@@constraints = constraints.inject({}) do |h, (k, v)| h[k.to_s] = v; h end
|
30
32
|
end
|
31
33
|
|
32
34
|
def lookup_all_indexes
|
@@ -37,6 +39,10 @@ DBLeftovers::DatabaseInterface.class_eval do
|
|
37
39
|
@@foreign_keys
|
38
40
|
end
|
39
41
|
|
42
|
+
def lookup_all_constraints
|
43
|
+
@@constraints
|
44
|
+
end
|
45
|
+
|
40
46
|
end
|
41
47
|
|
42
48
|
RSpec::Matchers.define :have_seen_sql do |sql|
|
@@ -58,6 +64,15 @@ describe DBLeftovers do
|
|
58
64
|
DBLeftovers::DatabaseInterface.sqls.should be_empty
|
59
65
|
end
|
60
66
|
|
67
|
+
it "should allow an empty table definition" do
|
68
|
+
DBLeftovers::DatabaseInterface.starts_with({}, {})
|
69
|
+
DBLeftovers::Definition.define do
|
70
|
+
table :books do
|
71
|
+
end
|
72
|
+
end
|
73
|
+
DBLeftovers::DatabaseInterface.sqls.should be_empty
|
74
|
+
end
|
75
|
+
|
61
76
|
it "should create indexes on an empty database" do
|
62
77
|
DBLeftovers::DatabaseInterface.starts_with({}, {})
|
63
78
|
DBLeftovers::Definition.define do
|
@@ -78,6 +93,32 @@ describe DBLeftovers do
|
|
78
93
|
EOQ
|
79
94
|
end
|
80
95
|
|
96
|
+
|
97
|
+
|
98
|
+
it "should create table-prefixed indexes on an empty database" do
|
99
|
+
DBLeftovers::DatabaseInterface.starts_with({}, {})
|
100
|
+
DBLeftovers::Definition.define do
|
101
|
+
table :books do
|
102
|
+
index :shelf_id
|
103
|
+
index :publisher_id, :where => 'published'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
DBLeftovers::DatabaseInterface.sqls.size.should == 2
|
107
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
108
|
+
CREATE INDEX index_books_on_shelf_id
|
109
|
+
ON books
|
110
|
+
(shelf_id)
|
111
|
+
EOQ
|
112
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
113
|
+
CREATE INDEX index_books_on_publisher_id
|
114
|
+
ON books
|
115
|
+
(publisher_id)
|
116
|
+
WHERE published
|
117
|
+
EOQ
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
|
81
122
|
it "should create foreign keys on an empty database" do
|
82
123
|
DBLeftovers::DatabaseInterface.starts_with({}, {})
|
83
124
|
DBLeftovers::Definition.define do
|
@@ -110,6 +151,40 @@ describe DBLeftovers do
|
|
110
151
|
|
111
152
|
|
112
153
|
|
154
|
+
it "should create table-prefixed foreign keys on an empty database" do
|
155
|
+
DBLeftovers::DatabaseInterface.starts_with({}, {})
|
156
|
+
DBLeftovers::Definition.define do
|
157
|
+
table :books do
|
158
|
+
foreign_key :shelf_id, :shelves
|
159
|
+
foreign_key :publisher_id, :publishers, :id, :set_null => true
|
160
|
+
foreign_key :author_id, :authors, :id, :cascade => true
|
161
|
+
end
|
162
|
+
end
|
163
|
+
DBLeftovers::DatabaseInterface.sqls.should have(3).items
|
164
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
165
|
+
ALTER TABLE books
|
166
|
+
ADD CONSTRAINT fk_books_shelf_id
|
167
|
+
FOREIGN KEY (shelf_id)
|
168
|
+
REFERENCES shelves (id)
|
169
|
+
EOQ
|
170
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
171
|
+
ALTER TABLE books
|
172
|
+
ADD CONSTRAINT fk_books_publisher_id
|
173
|
+
FOREIGN KEY (publisher_id)
|
174
|
+
REFERENCES publishers (id)
|
175
|
+
ON DELETE SET NULL
|
176
|
+
EOQ
|
177
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
178
|
+
ALTER TABLE books
|
179
|
+
ADD CONSTRAINT fk_books_author_id
|
180
|
+
FOREIGN KEY (author_id)
|
181
|
+
REFERENCES authors (id)
|
182
|
+
ON DELETE CASCADE
|
183
|
+
EOQ
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
|
113
188
|
it "should not create indexes when they already exist" do
|
114
189
|
DBLeftovers::DatabaseInterface.starts_with({
|
115
190
|
:index_books_on_shelf_id => DBLeftovers::Index.new(:books, :index_id),
|
@@ -126,6 +201,24 @@ describe DBLeftovers do
|
|
126
201
|
|
127
202
|
|
128
203
|
|
204
|
+
it "should not create table-prefixed indexes when they already exist" do
|
205
|
+
DBLeftovers::DatabaseInterface.starts_with({
|
206
|
+
:index_books_on_shelf_id => DBLeftovers::Index.new(:books, :index_id),
|
207
|
+
:index_books_on_publisher_id => DBLeftovers::Index.new(
|
208
|
+
:books, :publisher_id, :where => 'published')
|
209
|
+
}, {})
|
210
|
+
DBLeftovers::Definition.define do
|
211
|
+
table :books do
|
212
|
+
index :shelf_id
|
213
|
+
index :publisher_id, :where => 'published'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
DBLeftovers::DatabaseInterface.sqls.should have(0).items
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
|
129
222
|
it "should not create foreign keys when they already exist" do
|
130
223
|
DBLeftovers::DatabaseInterface.starts_with({}, {
|
131
224
|
:fk_books_shelf_id => DBLeftovers::ForeignKey.new('fk_books_shelf_id',
|
@@ -139,6 +232,21 @@ describe DBLeftovers do
|
|
139
232
|
|
140
233
|
|
141
234
|
|
235
|
+
it "should not create table-prefixed foreign keys when they already exist" do
|
236
|
+
DBLeftovers::DatabaseInterface.starts_with({}, {
|
237
|
+
:fk_books_shelf_id => DBLeftovers::ForeignKey.new('fk_books_shelf_id',
|
238
|
+
'books', 'shelf_id', 'shelves', 'id')
|
239
|
+
})
|
240
|
+
DBLeftovers::Definition.define do
|
241
|
+
table :books do
|
242
|
+
foreign_key :shelf_id, :shelves
|
243
|
+
end
|
244
|
+
end
|
245
|
+
DBLeftovers::DatabaseInterface.sqls.should have(0).items
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
|
142
250
|
it "should drop indexes when they are removed from the definition" do
|
143
251
|
DBLeftovers::DatabaseInterface.starts_with({
|
144
252
|
:index_books_on_shelf_id => DBLeftovers::Index.new(:books, :index_id),
|
@@ -173,4 +281,61 @@ describe DBLeftovers do
|
|
173
281
|
end
|
174
282
|
|
175
283
|
|
284
|
+
|
285
|
+
it "should support creating multi-column indexes" do
|
286
|
+
DBLeftovers::DatabaseInterface.starts_with({}, {})
|
287
|
+
DBLeftovers::Definition.define do
|
288
|
+
index :books, [:year, :title]
|
289
|
+
end
|
290
|
+
DBLeftovers::DatabaseInterface.sqls.should have(1).item
|
291
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
292
|
+
CREATE INDEX index_books_on_year_and_title
|
293
|
+
ON books
|
294
|
+
(year, title)
|
295
|
+
EOQ
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
|
300
|
+
it "should support dropping multi-column indexes" do
|
301
|
+
DBLeftovers::DatabaseInterface.starts_with({
|
302
|
+
:index_books_on_year_and_title => DBLeftovers::Index.new(:books, [:year, :title])
|
303
|
+
}, {})
|
304
|
+
DBLeftovers::Definition.define do
|
305
|
+
end
|
306
|
+
DBLeftovers::DatabaseInterface.sqls.should have(1).item
|
307
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
308
|
+
DROP INDEX index_books_on_year_and_title
|
309
|
+
EOQ
|
310
|
+
end
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
it "should allow mixing indexes and foreign keys in the same table" do
|
315
|
+
DBLeftovers::DatabaseInterface.starts_with({}, {})
|
316
|
+
DBLeftovers::Definition.define do
|
317
|
+
table :books do
|
318
|
+
index :author_id
|
319
|
+
foreign_key :author_id, :authors, :id
|
320
|
+
end
|
321
|
+
end
|
322
|
+
DBLeftovers::DatabaseInterface.sqls.should have(2).items
|
323
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
324
|
+
CREATE INDEX index_books_on_author_id
|
325
|
+
ON books
|
326
|
+
(author_id)
|
327
|
+
EOQ
|
328
|
+
DBLeftovers::DatabaseInterface.should have_seen_sql <<-EOQ
|
329
|
+
ALTER TABLE books
|
330
|
+
ADD CONSTRAINT fk_books_author_id
|
331
|
+
FOREIGN KEY (author_id)
|
332
|
+
REFERENCES authors (id)
|
333
|
+
EOQ
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
|
338
|
+
it "should allow separating indexes and foreign keys from the same table" do
|
339
|
+
end
|
340
|
+
|
176
341
|
end
|
data/spec/spec_helper.rb
CHANGED
File without changes
|
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.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,32 +21,47 @@ dependencies:
|
|
21
21
|
version: 3.0.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.0.0
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rspec
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
31
36
|
- !ruby/object:Gem::Version
|
32
|
-
version: 2.
|
37
|
+
version: 2.4.0
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.4.0
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: bundler
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
|
-
- -
|
51
|
+
- - ! '>='
|
42
52
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
53
|
+
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: jeweler
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ~>
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: 1.6.4
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.6.4
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: rcov
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,7 +85,12 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
description: ! " Define indexes and foreign keys for your Rails app\n in
|
70
95
|
one place using an easy-to-read DSL,\n then run a rake task to bring your
|
71
96
|
database up-to-date.\n"
|
@@ -87,6 +112,7 @@ files:
|
|
87
112
|
- VERSION
|
88
113
|
- db_leftovers.gemspec
|
89
114
|
- lib/db_leftovers.rb
|
115
|
+
- lib/db_leftovers/constraint.rb
|
90
116
|
- lib/db_leftovers/database_interface.rb
|
91
117
|
- lib/db_leftovers/definition.rb
|
92
118
|
- lib/db_leftovers/dsl.rb
|
@@ -113,7 +139,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
139
|
version: '0'
|
114
140
|
segments:
|
115
141
|
- 0
|
116
|
-
hash: -
|
142
|
+
hash: -2560177434569701108
|
117
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
144
|
none: false
|
119
145
|
requirements:
|
@@ -122,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
148
|
version: '0'
|
123
149
|
requirements: []
|
124
150
|
rubyforge_project:
|
125
|
-
rubygems_version: 1.8.
|
151
|
+
rubygems_version: 1.8.24
|
126
152
|
signing_key:
|
127
153
|
specification_version: 3
|
128
154
|
summary: Used to define indexes and foreign keys for your Rails app
|