db_leftovers 0.9.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document CHANGED
File without changes
data/Gemfile CHANGED
@@ -17,3 +17,7 @@ group :development do
17
17
  gem "rcov", ">= 0"
18
18
  end
19
19
 
20
+ group :test do
21
+ gem 'activerecord-postgresql-adapter'
22
+ gem 'activerecord-mysql2-adapter'
23
+ end
data/Gemfile.lock CHANGED
@@ -24,6 +24,10 @@ GEM
24
24
  activesupport (= 3.1.3)
25
25
  arel (~> 2.2.1)
26
26
  tzinfo (~> 0.3.29)
27
+ activerecord-mysql2-adapter (0.0.3)
28
+ mysql2
29
+ activerecord-postgresql-adapter (0.0.1)
30
+ pg
27
31
  activeresource (3.1.3)
28
32
  activemodel (= 3.1.3)
29
33
  activesupport (= 3.1.3)
@@ -47,6 +51,8 @@ GEM
47
51
  treetop (~> 1.4.8)
48
52
  mime-types (1.17.2)
49
53
  multi_json (1.0.4)
54
+ mysql2 (0.3.11)
55
+ pg (0.14.1)
50
56
  polyglot (0.3.3)
51
57
  rack (1.3.6)
52
58
  rack-cache (1.1)
@@ -99,6 +105,8 @@ PLATFORMS
99
105
  ruby
100
106
 
101
107
  DEPENDENCIES
108
+ activerecord-mysql2-adapter
109
+ activerecord-postgresql-adapter
102
110
  bundler
103
111
  jeweler (~> 1.6.4)
104
112
  rails (>= 3.0.0)
data/LICENSE.txt CHANGED
File without changes
data/README.html CHANGED
@@ -3,12 +3,19 @@
3
3
  <p>db_leftovers lets you define indexes, foreign keys, and CHECK constraints for your Rails app
4
4
  in one place using an easy-to-read DSL,
5
5
  then run a rake task to bring your database up-to-date.
6
- I wrote this because I didn't want indexes and constraints scattered throughout my migrations or buried in my <code>schema.rb</code>, and I wanted a command I could run to ensure that they matched across my development, test, staging, and production databases.
7
- This was particularly a problem for Heroku projects, because <code>db:push</code> and <code>db:pull</code> do not transfer your foreign keys or other constraints.
8
- But now that it's written, I'm finding it useful on non-Heroku projects as well.</p>
6
+ Whenever you edit the DSL, you can re-run the rake task and db_leftovers will alter your database accorindgly.
7
+ This is useful because of the following limitations in vanilla Rails:</p>
9
8
 
10
- <p>At present db_leftovers works only on PostgreSQL databases,
11
- but it could easily be extended to cover other RDBMSes.</p>
9
+ <ul>
10
+ <li>There are no built-in migration methods to create foreign keys or CHECK constraints.</li>
11
+ <li>Even if created, foreign keys and CHECK constraints won't appear in your schema.rb.</li>
12
+ <li>If you're using Heroku, <code>db:push</code> and <code>db:pull</code> won't transfer your foreign keys and CHECK constraints.</li>
13
+ <li>Creating indexes in your migrations makes it hard to manage them.</li>
14
+ </ul>
15
+
16
+ <p>That last point deserves some elaboration. Using <code>create_index</code> in your migrations is bug-prone because without rare developer discipline (My rule is "never change a migration after a <code>git push</code>, but I haven't seen this followed elsewhere."), you wind up missing indexes in some environments. It also means you don't have a central place to see all your indexes so you can analyze which are needed. With db_leftovers, you can rest assured that each environment conforms to a definition that is easy to read and checked into version control.</p>
17
+
18
+ <p>At present db_leftovers supports PostgreSQL and MySQL, although since MySQL doesn't support index WHERE clauses or CHECK constraints, using that functionality will raise errors. (If you need to share the same definitions across Postgres and MySQL, you can run arbitrary Ruby code inside the DSL to avoid defining unsupported objects when run against MySQL.)</p>
12
19
 
13
20
  <h2>Configuration File</h2>
14
21
 
@@ -70,7 +77,7 @@ All parameters are strings or symbols.</p>
70
77
 
71
78
  <h3>table(table_name, &amp;block)</h3>
72
79
 
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>
80
+ <p>The <code>table</code> call is just a convenience so you can group all a table's indexes et cetera together and not keep repeating the table name. You use it like this:</p>
74
81
 
75
82
  <pre><code>table :books do
76
83
  index :author_id
@@ -104,7 +111,8 @@ The second time you run db_leftovers, it will read the expression from Postgres
104
111
  and so it will drop and re-create the constraint.
105
112
  It will drop and re-create it every time you run the rake task.
106
113
  To get around this, make sure your config file uses the same expression as printed by db_leftovers in the rake output.
107
- This can also happen for index WHERE clauses, fixable by a similar workaround.</p>
114
+ This can also happen for index WHERE clauses, fixable by a similar workaround.
115
+ MySQL doesn't have this problem because it doesn't support CHECK constraints or index WHERE clauses.</p>
108
116
 
109
117
  <p>To print messages even about indexes/foreign keys/constraints that haven't changed, you can say:</p>
110
118
 
@@ -119,8 +127,7 @@ This can also happen for index WHERE clauses, fixable by a similar workaround.</
119
127
  <h2>Known Issues</h2>
120
128
 
121
129
  <ul>
122
- <li>db_leftovers only supports PostgreSQL databases.
123
- If you want to add support for something else, just send me a pull request!</li>
130
+ <li>When db_leftovers interrogates your database for the currently-defined indexes et cetera, it doesn't filter things by the current database name. So if you have mutliple Rails projects all accessible to the same user, you'll wind up changing more than you like (probably by DROPing things).</li>
124
131
  </ul>
125
132
 
126
133
  <h2>Contributing to db_leftovers</h2>
data/README.md CHANGED
@@ -4,12 +4,17 @@ db\_leftovers
4
4
  db\_leftovers lets you define indexes, foreign keys, and CHECK constraints for your Rails app
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
- I wrote this because I didn't want indexes and constraints scattered throughout my migrations or buried in my `schema.rb`, and I wanted a command I could run to ensure that they matched across my development, test, staging, and production databases.
8
- This was particularly a problem for Heroku projects, because `db:push` and `db:pull` do not transfer your foreign keys or other constraints.
9
- But now that it's written, I'm finding it useful on non-Heroku projects as well.
7
+ Whenever you edit the DSL, you can re-run the rake task and db\_leftovers will alter your database accorindgly.
8
+ This is useful because of the following limitations in vanilla Rails:
10
9
 
11
- At present db\_leftovers works only on PostgreSQL databases,
12
- but it could easily be extended to cover other RDBMSes.
10
+ * There are no built-in migration methods to create foreign keys or CHECK constraints.
11
+ * Even if created, foreign keys and CHECK constraints won't appear in your schema.rb.
12
+ * If you're using Heroku, `db:push` and `db:pull` won't transfer your foreign keys and CHECK constraints.
13
+ * Creating indexes in your migrations makes it hard to manage them.
14
+
15
+ That last point deserves some elaboration. Using `create_index` in your migrations is bug-prone because without rare developer discipline (My rule is "never change a migration after a `git push`, but I haven't seen this followed elsewhere."), you wind up missing indexes in some environments. It also means you don't have a central place to see all your indexes so you can analyze which are needed. With db\_leftovers, you can rest assured that each environment conforms to a definition that is easy to read and checked into version control.
16
+
17
+ At present db\_leftovers supports PostgreSQL and MySQL, although since MySQL doesn't support index WHERE clauses or CHECK constraints, using that functionality will raise errors. (If you need to share the same definitions across Postgres and MySQL, you can run arbitrary Ruby code inside the DSL to avoid defining unsupported objects when run against MySQL.)
13
18
 
14
19
  Configuration File
15
20
  ------------------
@@ -66,7 +71,7 @@ All parameters are strings or symbols.
66
71
 
67
72
  ### table(table\_name, &block)
68
73
 
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:
74
+ The `table` call is just a convenience so you can group all a table's indexes et cetera together and not keep repeating the table name. You use it like this:
70
75
 
71
76
  table :books do
72
77
  index :author_id
@@ -100,6 +105,7 @@ and so it will drop and re-create the constraint.
100
105
  It will drop and re-create it every time you run the rake task.
101
106
  To get around this, make sure your config file uses the same expression as printed by db\_leftovers in the rake output.
102
107
  This can also happen for index WHERE clauses, fixable by a similar workaround.
108
+ MySQL doesn't have this problem because it doesn't support CHECK constraints or index WHERE clauses.
103
109
 
104
110
  To print messages even about indexes/foreign keys/constraints that haven't changed, you can say:
105
111
 
@@ -115,8 +121,7 @@ or
115
121
  Known Issues
116
122
  ------------
117
123
 
118
- * db\_leftovers only supports PostgreSQL databases.
119
- If you want to add support for something else, just send me a pull request!
124
+ * When db\_leftovers interrogates your database for the currently-defined indexes et cetera, it doesn't filter things by the current database name. So if you have mutliple Rails projects all accessible to the same user, you'll wind up changing more than you like (probably by DROPing things).
120
125
 
121
126
 
122
127
 
data/Rakefile CHANGED
File without changes
data/TODO CHANGED
@@ -1,9 +1,2 @@
1
- - Refactor DatabaseInterface so all methods are instance methods and Definition/DSL uses an instance, set according to the Rails database adapter and also settable to a test subclass, so we can change the definition from test to test.
2
-
3
- - Add optional tests that use a real Postgres/MySQL/SQLite if available.
4
- - Run all the same tests, but against a real DatabaseInterface instance.
5
-
6
1
  - Make sure everything works if the current db user has access to multiple databases: only run the code on the db given in the Rails database.yml.
7
2
 
8
- - Support MySQL
9
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.2
1
+ 1.0.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.9.2"
8
+ s.version = "1.0.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-09-30"
12
+ s.date = "2012-10-02"
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 = [
@@ -30,15 +30,23 @@ Gem::Specification.new do |s|
30
30
  "db_leftovers.gemspec",
31
31
  "lib/db_leftovers.rb",
32
32
  "lib/db_leftovers/constraint.rb",
33
- "lib/db_leftovers/database_interface.rb",
34
33
  "lib/db_leftovers/definition.rb",
35
34
  "lib/db_leftovers/dsl.rb",
36
35
  "lib/db_leftovers/foreign_key.rb",
36
+ "lib/db_leftovers/generic_database_interface.rb",
37
37
  "lib/db_leftovers/index.rb",
38
+ "lib/db_leftovers/mysql_database_interface.rb",
39
+ "lib/db_leftovers/postgres_database_interface.rb",
38
40
  "lib/db_leftovers/table_dsl.rb",
39
41
  "lib/tasks/leftovers.rake",
42
+ "spec/config/database.yml.sample",
40
43
  "spec/db_leftovers_spec.rb",
41
- "spec/spec_helper.rb"
44
+ "spec/mysql_spec.rb",
45
+ "spec/postgres_spec.rb",
46
+ "spec/spec_helper.rb",
47
+ "spec/support/mock_database_interface.rb",
48
+ "spec/support/shared_db_tests.rb",
49
+ "spec/support/sql_matcher.rb"
42
50
  ]
43
51
  s.homepage = "http://github.com/pjungwir/db_leftovers"
44
52
  s.licenses = ["MIT"]
data/lib/db_leftovers.rb CHANGED
@@ -1,4 +1,6 @@
1
- require 'db_leftovers/database_interface.rb'
1
+ require 'db_leftovers/generic_database_interface.rb'
2
+ require 'db_leftovers/postgres_database_interface.rb'
3
+ require 'db_leftovers/mysql_database_interface.rb'
2
4
  require 'db_leftovers/index.rb'
3
5
  require 'db_leftovers/foreign_key.rb'
4
6
  require 'db_leftovers/constraint.rb'
File without changes
@@ -5,9 +5,12 @@ module DBLeftovers
5
5
  opts = {
6
6
  :do_indexes => true,
7
7
  :do_foreign_keys => true,
8
- :do_constraints => true
8
+ :do_constraints => true,
9
+ :db_interface => nil
9
10
  }.merge(opts)
10
- dsl = DSL.new(:verbose => ENV['DB_LEFTOVERS_VERBOSE'] || false)
11
+ dsl = DSL.new(
12
+ :verbose => ENV['DB_LEFTOVERS_VERBOSE'] || false,
13
+ :db_interface => opts[:db_interface])
11
14
  dsl.define(&block)
12
15
  dsl.record_indexes if opts[:do_indexes]
13
16
  dsl.record_foreign_keys if opts[:do_foreign_keys]
@@ -8,7 +8,7 @@ module DBLeftovers
8
8
 
9
9
  def initialize(opts={})
10
10
  @verbose = !!opts[:verbose]
11
- @db = DatabaseInterface.new
11
+ @db = opts[:db_interface] || get_database_interface
12
12
 
13
13
  @indexes_by_table = {} # Set from the DSL
14
14
  @old_indexes = @db.lookup_all_indexes
@@ -226,6 +226,18 @@ module DBLeftovers
226
226
  "fk_#{from_table}_#{from_column}"
227
227
  end
228
228
 
229
+ def get_database_interface
230
+ db = ActiveRecord::Base.configurations[Rails.env]['adapter']
231
+ case db
232
+ when 'postgresql'
233
+ DBLeftovers::PostgresDatabaseInterface.new
234
+ when 'mysql2'
235
+ DBLeftovers::MySQLInterface.new
236
+ else
237
+ raise "Unsupported database: #{db}"
238
+ end
239
+ end
240
+
229
241
  end
230
242
 
231
243
  end
File without changes
@@ -0,0 +1,67 @@
1
+ module DBLeftovers
2
+
3
+ class GenericDatabaseInterface
4
+
5
+ def lookup_all_indexes
6
+ raise "Should be overriden by a database-specific interface"
7
+ end
8
+
9
+ def lookup_all_foreign_keys
10
+ raise "Should be overriden by a database-specific interface"
11
+ end
12
+
13
+ def lookup_all_constraints
14
+ raise "Should be overriden by a database-specific interface"
15
+ end
16
+
17
+ def execute_add_index(idx)
18
+ unique = idx.unique? ? 'UNIQUE' : ''
19
+ where = idx.where_clause.present? ? "WHERE #{idx.where_clause}" : ''
20
+
21
+ sql = <<-EOQ
22
+ CREATE #{unique} INDEX #{idx.index_name}
23
+ ON #{idx.table_name}
24
+ (#{idx.column_names.join(', ')})
25
+ #{where}
26
+ EOQ
27
+ execute_sql(sql)
28
+ end
29
+
30
+ def execute_drop_index(table_name, index_name)
31
+ sql = <<-EOQ
32
+ DROP INDEX #{index_name}
33
+ EOQ
34
+ execute_sql(sql)
35
+ end
36
+
37
+ def execute_add_foreign_key(fk)
38
+ on_delete = "ON DELETE CASCADE" if fk.cascade
39
+ on_delete = "ON DELETE SET NULL" if fk.set_null
40
+ execute_sql %{ALTER TABLE #{fk.from_table}
41
+ ADD CONSTRAINT #{fk.constraint_name}
42
+ FOREIGN KEY (#{fk.from_column})
43
+ REFERENCES #{fk.to_table} (#{fk.to_column})
44
+ #{on_delete}}
45
+ end
46
+
47
+ def execute_drop_foreign_key(constraint_name, from_table, from_column)
48
+ execute_sql %{ALTER TABLE #{from_table} DROP CONSTRAINT #{constraint_name}}
49
+ end
50
+
51
+ def execute_add_constraint(chk)
52
+ sql = <<-EOQ
53
+ ALTER TABLE #{chk.on_table} ADD CONSTRAINT #{chk.constraint_name} CHECK (#{chk.check})
54
+ EOQ
55
+ execute_sql sql
56
+ end
57
+
58
+ def execute_drop_constraint(constraint_name, on_table)
59
+ execute_sql %{ALTER TABLE #{on_table} DROP CONSTRAINT #{constraint_name}}
60
+ end
61
+
62
+ def execute_sql(sql)
63
+ @conn.execute(sql)
64
+ end
65
+
66
+ end
67
+ end
File without changes
@@ -0,0 +1,83 @@
1
+ module DBLeftovers
2
+
3
+ class MysqlDatabaseInterface < GenericDatabaseInterface
4
+
5
+ def initialize(conn=nil)
6
+ @conn = conn || ActiveRecord::Base.connection
7
+ end
8
+
9
+ def lookup_all_indexes
10
+ # TODO: Constrain it to the database for the current Rails project:
11
+ ret = {}
12
+ @conn.select_values("SHOW TABLES").each do |table_name|
13
+ indexes = {}
14
+ # Careful, MySQL automatically creates indexes whenever you define a foreign key.
15
+ # Use our foreign key naming convention to ignore these:
16
+ @conn.select_rows("SHOW INDEXES FROM #{table_name} WHERE key_name NOT LIKE 'fk_%'").each do |_, non_unique, key_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, has_nulls, index_type, comment|
17
+ unless key_name == 'PRIMARY'
18
+ # Combine rows for multi-column indexes
19
+ h = (indexes[key_name] ||= { unique: non_unique == 0, name: key_name, columns: {} })
20
+ h[:columns][seq_in_index.to_i] = column_name
21
+ end
22
+ end
23
+
24
+ indexes.each do |index_name, h|
25
+ ret[index_name] = Index.new(
26
+ table_name,
27
+ h[:columns].sort.map{|k, v| v},
28
+ unique: h[:unique],
29
+ name: h[:name]
30
+ )
31
+ end
32
+ end
33
+
34
+ return ret
35
+ end
36
+
37
+ def lookup_all_foreign_keys
38
+ # TODO: Support multi-column foreign keys:
39
+ # TODO: Constrain it to the database for the current Rails project:
40
+ ret = {}
41
+ sql = <<-EOQ
42
+ SELECT c.constraint_name,
43
+ c.table_name,
44
+ k.column_name,
45
+ c.referenced_table_name,
46
+ k.referenced_column_name,
47
+ c.delete_rule
48
+ FROM information_schema.referential_constraints c,
49
+ information_schema.key_column_usage k
50
+ WHERE c.constraint_schema = k.constraint_schema
51
+ AND c.constraint_name = k.constraint_name
52
+ EOQ
53
+ @conn.select_rows(sql).each do |constr_name, from_table, from_column, to_table, to_column, del_type|
54
+ del_type = case del_type
55
+ when 'RESTRICT'; nil
56
+ when 'CASCADE'; :cascade
57
+ when 'SET NULL'; :set_null
58
+ else; raise "Unknown del type: #{del_type}"
59
+ end
60
+ ret[constr_name] = ForeignKey.new(constr_name, from_table, from_column, to_table, to_column, :on_delete => del_type)
61
+ end
62
+ return ret
63
+ end
64
+
65
+ def lookup_all_constraints
66
+ # TODO: Constrain it to the database for the current Rails project:
67
+ # MySQL doesn't support CHECK constraints:
68
+ return []
69
+ end
70
+
71
+ def execute_drop_index(table_name, index_name)
72
+ sql = <<-EOQ
73
+ DROP INDEX #{index_name} ON #{table_name}
74
+ EOQ
75
+ execute_sql(sql)
76
+ end
77
+
78
+ def execute_drop_foreign_key(constraint_name, from_table, from_column)
79
+ execute_sql %{ALTER TABLE #{from_table} DROP FOREIGN KEY #{constraint_name}}
80
+ end
81
+
82
+ end
83
+ end
@@ -1,9 +1,14 @@
1
1
  module DBLeftovers
2
2
 
3
- class DatabaseInterface
3
+ class PostgresDatabaseInterface < GenericDatabaseInterface
4
+
5
+ def initialize(conn=nil)
6
+ @conn = conn || ActiveRecord::Base.connection
7
+ end
4
8
 
5
9
  def lookup_all_indexes
6
- # TODO: Constraint it to the database for the current Rails project:
10
+ # TODO: Constrain it to the database for the current Rails project:
11
+ # (current_database(), current_schema())
7
12
  ret = {}
8
13
  sql = <<-EOQ
9
14
  SELECT ix.indexrelid,
@@ -34,7 +39,7 @@ module DBLeftovers
34
39
  ix.indpred
35
40
  ORDER BY t.relname, i.relname
36
41
  EOQ
37
- ActiveRecord::Base.connection.select_rows(sql).each do |indexrelid, indrelid, table_name, index_name, is_unique, column_numbers, where_clause|
42
+ @conn.select_rows(sql).each do |indexrelid, indrelid, table_name, index_name, is_unique, column_numbers, where_clause|
38
43
  where_clause = remove_outer_parens(where_clause) if where_clause
39
44
  ret[index_name] = Index.new(
40
45
  table_name,
@@ -53,7 +58,8 @@ module DBLeftovers
53
58
  # confdeltype: a=nil, c=cascade, n=null
54
59
  ret = {}
55
60
  # TODO: Support multi-column foreign keys:
56
- # TODO: Constraint it to the database for the current Rails project:
61
+ # TODO: Constrain it to the database for the current Rails project:
62
+ # (current_database(), current_schema())
57
63
  sql = <<-EOQ
58
64
  SELECT c.conname,
59
65
  t1.relname,
@@ -84,7 +90,7 @@ module DBLeftovers
84
90
  AND pg_catalog.pg_table_is_visible(t1.oid)
85
91
  AND pg_catalog.pg_table_is_visible(t2.oid)
86
92
  EOQ
87
- ActiveRecord::Base.connection.select_rows(sql).each do |constr_name, from_table, from_column, to_table, to_column, del_type|
93
+ @conn.select_rows(sql).each do |constr_name, from_table, from_column, to_table, to_column, del_type|
88
94
  del_type = case del_type
89
95
  when 'a'; nil
90
96
  when 'c'; :cascade
@@ -97,7 +103,8 @@ module DBLeftovers
97
103
  end
98
104
 
99
105
  def lookup_all_constraints
100
- # TODO: Constraint it to the database for the current Rails project:
106
+ # TODO: Constrain it to the database for the current Rails project:
107
+ # (current_database(), current_schema())
101
108
  ret = {}
102
109
  sql = <<-EOQ
103
110
  SELECT c.conname,
@@ -113,61 +120,12 @@ module DBLeftovers
113
120
  AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
114
121
  AND pg_catalog.pg_table_is_visible(t.oid)
115
122
  EOQ
116
- ActiveRecord::Base.connection.select_rows(sql).each do |constr_name, on_table, check_expr|
123
+ @conn.select_rows(sql).each do |constr_name, on_table, check_expr|
117
124
  ret[constr_name] = Constraint.new(constr_name, on_table, remove_outer_parens(check_expr))
118
125
  end
119
126
  return ret
120
127
  end
121
128
 
122
- def execute_add_index(idx)
123
- unique = idx.unique? ? 'UNIQUE' : ''
124
- where = idx.where_clause.present? ? "WHERE #{idx.where_clause}" : ''
125
-
126
- sql = <<-EOQ
127
- CREATE #{unique} INDEX #{idx.index_name}
128
- ON #{idx.table_name}
129
- (#{idx.column_names.join(', ')})
130
- #{where}
131
- EOQ
132
- execute_sql(sql)
133
- end
134
-
135
- def execute_drop_index(table_name, index_name)
136
- sql = <<-EOQ
137
- DROP INDEX #{index_name}
138
- EOQ
139
- execute_sql(sql)
140
- end
141
-
142
- def execute_add_foreign_key(fk)
143
- on_delete = "ON DELETE CASCADE" if fk.cascade
144
- on_delete = "ON DELETE SET NULL" if fk.set_null
145
- execute_sql %{ALTER TABLE #{fk.from_table}
146
- ADD CONSTRAINT #{fk.constraint_name}
147
- FOREIGN KEY (#{fk.from_column})
148
- REFERENCES #{fk.to_table} (#{fk.to_column})
149
- #{on_delete}}
150
- end
151
-
152
- def execute_drop_foreign_key(constraint_name, from_table, from_column)
153
- execute_sql %{ALTER TABLE #{from_table} DROP CONSTRAINT #{constraint_name}}
154
- end
155
-
156
- def execute_add_constraint(chk)
157
- sql = <<-EOQ
158
- ALTER TABLE #{chk.on_table} ADD CONSTRAINT #{chk.constraint_name} CHECK (#{chk.check})
159
- EOQ
160
- execute_sql sql
161
- end
162
-
163
- def execute_drop_constraint(constraint_name, on_table)
164
- execute_sql %{ALTER TABLE #{on_table} DROP CONSTRAINT #{constraint_name}}
165
- end
166
-
167
- def execute_sql(sql)
168
- ActiveRecord::Base.connection.execute(sql)
169
- end
170
-
171
129
  private
172
130
 
173
131
  def column_names_for_index(table_id, column_numbers)
@@ -178,7 +136,7 @@ module DBLeftovers
178
136
  WHERE attrelid = #{table_id}
179
137
  AND attnum = #{c}
180
138
  EOQ
181
- ActiveRecord::Base.connection.select_value(sql)
139
+ @conn.select_value(sql)
182
140
  end
183
141
  end
184
142
 
@@ -186,6 +144,5 @@ module DBLeftovers
186
144
  str ? str.gsub(/^\((.*)\)$/, '\1') : nil
187
145
  end
188
146
 
189
-
190
147
  end
191
148
  end