schema_plus 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +29 -0
- data/README.md +19 -0
- data/gemfiles/rails-3.2/Gemfile.mysql +7 -1
- data/gemfiles/rails-3.2/Gemfile.mysql2 +7 -1
- data/gemfiles/rails-3.2/Gemfile.postgresql +7 -1
- data/gemfiles/rails-3.2/Gemfile.sqlite3 +7 -1
- data/gemfiles/rails-4.0/Gemfile.mysql2 +7 -1
- data/gemfiles/rails-4.0/Gemfile.postgresql +7 -1
- data/gemfiles/rails-4.0/Gemfile.sqlite3 +7 -1
- data/gemfiles/rails-edge/Gemfile.mysql2 +7 -1
- data/gemfiles/rails-edge/Gemfile.postgresql +7 -1
- data/gemfiles/rails-edge/Gemfile.sqlite3 +7 -1
- data/lib/schema_plus/active_record/column_options_handler.rb +2 -2
- data/lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb +124 -57
- data/lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb +9 -2
- data/lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb +30 -10
- data/lib/schema_plus/active_record/connection_adapters/postgresql_adapter.rb +55 -30
- data/lib/schema_plus/active_record/connection_adapters/schema_statements.rb +1 -0
- data/lib/schema_plus/active_record/connection_adapters/sqlite3_adapter.rb +10 -7
- data/lib/schema_plus/active_record/connection_adapters/table_definition.rb +7 -16
- data/lib/schema_plus/active_record/migration/command_recorder.rb +88 -0
- data/lib/schema_plus/active_record/schema_dumper.rb +1 -1
- data/lib/schema_plus/version.rb +1 -1
- data/lib/schema_plus.rb +10 -1
- data/runspecs +24 -5
- data/spec/column_definition_spec.rb +69 -9
- data/spec/index_definition_spec.rb +25 -0
- data/spec/index_spec.rb +1 -1
- data/spec/migration_spec.rb +76 -11
- data/spec/schema_dumper_spec.rb +19 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f36351daeeb9863e7b0344d565b2f67125ed9cea
|
4
|
+
data.tar.gz: cb88da4066f4db2f2dfb35f018cc38d82cf6aebc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7f2ab813dcf8bd3c02c780337fefc2ae2c5cd793dee59b1cecc76d1706749918bf534685d3d53b7c31bce4989b56e906d292ff1c254f26e9f80d56ac450aca3
|
7
|
+
data.tar.gz: 79c000eaa5312482df33ec2d09638d93038ba213320172eb6a029a077efbb41164996cc344a8f3325b06d4cb7702a9aaa3153eeba8f65acf9a9e33e2bc80a651
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
rvm:
|
2
2
|
- 1.9.3
|
3
3
|
- 2.0.0
|
4
|
+
- jruby
|
4
5
|
gemfile:
|
5
6
|
- gemfiles/rails-3.2/Gemfile.postgresql
|
6
7
|
- gemfiles/rails-3.2/Gemfile.sqlite3
|
@@ -26,3 +27,31 @@ matrix:
|
|
26
27
|
- gemfile: gemfiles/rails-edge/Gemfile.postgresql
|
27
28
|
- gemfile: gemfiles/rails-edge/Gemfile.sqlite3
|
28
29
|
- gemfile: gemfiles/rails-edge/Gemfile.mysql2
|
30
|
+
exclude:
|
31
|
+
- rvm: jruby
|
32
|
+
gemfile: gemfiles/rails-3.2/Gemfile.sqlite3
|
33
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
34
|
+
- rvm: jruby
|
35
|
+
gemfile: gemfiles/rails-3.2/Gemfile.mysql
|
36
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
37
|
+
- rvm: jruby
|
38
|
+
gemfile: gemfiles/rails-3.2/Gemfile.mysql2
|
39
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
40
|
+
- rvm: jruby
|
41
|
+
gemfile: gemfiles/rails-4.0/Gemfile.postgresql
|
42
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
43
|
+
- rvm: jruby
|
44
|
+
gemfile: gemfiles/rails-4.0/Gemfile.sqlite3
|
45
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
46
|
+
- rvm: jruby
|
47
|
+
gemfile: gemfiles/rails-4.0/Gemfile.mysql2
|
48
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
49
|
+
- rvm: jruby
|
50
|
+
gemfile: gemfiles/rails-edge/Gemfile.postgresql
|
51
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
52
|
+
- rvm: jruby
|
53
|
+
gemfile: gemfiles/rails-edge/Gemfile.sqlite3
|
54
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
55
|
+
- rvm: jruby
|
56
|
+
gemfile: gemfiles/rails-edge/Gemfile.mysql2
|
57
|
+
env: 'POSTGRES_DB_USER=postgres MYSQL_DB_USER=""'
|
data/README.md
CHANGED
@@ -22,6 +22,10 @@ SchemaPlus supports all combinations of:
|
|
22
22
|
3.2), or SQLite3 (using sqlite3 >= 3.7.7 which has foreign key support)
|
23
23
|
* MRI Ruby 1.9.3 or 2.0.0
|
24
24
|
|
25
|
+
And also supports:
|
26
|
+
|
27
|
+
* jruby with Rails 3.2 and PostgreSQL
|
28
|
+
|
25
29
|
|
26
30
|
Note: As of version 1.0.0, SchemaPlus no longer supports Rails 2.3, 3.0 and
|
27
31
|
3.1, and also no longer supports MRI Ruby 1.8.7; the last version
|
@@ -118,6 +122,8 @@ SchemaPlus also tidies some index-related behavior:
|
|
118
122
|
* If you rename a table, indexes named using rails' automatic naming
|
119
123
|
convention will be renamed correspondingly.
|
120
124
|
|
125
|
+
* `remove_index` now accepts an `:if_exists` option to prevent errors from attempting to remove non-existent indexes.
|
126
|
+
|
121
127
|
|
122
128
|
### Foreign Key Constraints
|
123
129
|
|
@@ -290,6 +296,19 @@ of foreign key constraints, you can re-enable it:
|
|
290
296
|
|
291
297
|
## Release notes:
|
292
298
|
|
299
|
+
### Master branch (to be released)
|
300
|
+
|
301
|
+
* (nothing new yet)
|
302
|
+
|
303
|
+
### 1.3.0
|
304
|
+
|
305
|
+
* Added :if_exists option for remove_index
|
306
|
+
* Initial jruby support (rails 3.2, postgresql), due to efforts of [@donv](https://github.com/donv)
|
307
|
+
* Preliminatry groundwork for rails 4.1, due to efforts of [@tovodeverett](https://github.com/tovodeverett)
|
308
|
+
* Bug fix for change_table
|
309
|
+
* Bug fix for schema_dump postgresql non-btree indexes
|
310
|
+
* Bug fix regarding expressions that cast non-string columns to strings in a lower()
|
311
|
+
|
293
312
|
### 1.2.0
|
294
313
|
* Now works with rails 4, due to efforts of [@tovodeverett](https://github.com/tovodeverett)
|
295
314
|
* Test against MRI ruby 2.0.0, no longer test against 1.9.2
|
@@ -73,7 +73,7 @@ module SchemaPlus::ActiveRecord
|
|
73
73
|
def remove_foreign_key_if_exists(table_name, column_name) #:nodoc:
|
74
74
|
foreign_keys = ActiveRecord::Base.connection.foreign_keys(table_name.to_s) rescue [] # no fks if table_name doesn't exist
|
75
75
|
fk = foreign_keys.detect { |fk| fk.table_name == table_name.to_s && fk.column_names == Array(column_name).collect(&:to_s) }
|
76
|
-
remove_foreign_key(table_name, fk.
|
76
|
+
remove_foreign_key(table_name, fk.column_names, fk.references_table_name, fk.references_column_names) if fk
|
77
77
|
end
|
78
78
|
|
79
79
|
|
@@ -86,7 +86,7 @@ module SchemaPlus::ActiveRecord
|
|
86
86
|
|
87
87
|
def remove_auto_index_if_exists(table_name, column_name)
|
88
88
|
name = auto_index_name(table_name, column_name)
|
89
|
-
remove_index(table_name, :name => name
|
89
|
+
remove_index(table_name, :name => name, :column => column_name, :if_exists => true)
|
90
90
|
end
|
91
91
|
|
92
92
|
def auto_index_name(table_name, column_name)
|
@@ -13,6 +13,7 @@ module SchemaPlus
|
|
13
13
|
module AbstractAdapter
|
14
14
|
def self.included(base) #:nodoc:
|
15
15
|
base.alias_method_chain :initialize, :schema_plus
|
16
|
+
base.alias_method_chain :remove_index, :schema_plus
|
16
17
|
end
|
17
18
|
|
18
19
|
def initialize_with_schema_plus(*args) #:nodoc:
|
@@ -31,6 +32,13 @@ module SchemaPlus
|
|
31
32
|
# for this.
|
32
33
|
adapter_module = SchemaPlus::ActiveRecord::ConnectionAdapters.const_get(adapter)
|
33
34
|
self.class.send(:include, adapter_module) unless self.class.include?(adapter_module)
|
35
|
+
|
36
|
+
if "#{::ActiveRecord::VERSION::MAJOR}.#{::ActiveRecord::VERSION::MINOR}".to_r >= "4.1".to_r
|
37
|
+
self.class.const_get(:SchemaCreation).send(:include, adapter_module.const_get(:AddColumnOptions))
|
38
|
+
else
|
39
|
+
self.class.send(:include, adapter_module.const_get(:AddColumnOptions))
|
40
|
+
end
|
41
|
+
|
34
42
|
extend(SchemaPlus::ActiveRecord::ForeignKeys)
|
35
43
|
end
|
36
44
|
|
@@ -57,17 +65,56 @@ module SchemaPlus
|
|
57
65
|
# it's created. If you're using Sqlite3, this method will raise an
|
58
66
|
# error.)
|
59
67
|
def add_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {})
|
60
|
-
|
61
|
-
execute "ALTER TABLE #{quote_table_name(table_name)}
|
68
|
+
foreign_key_sql = add_foreign_key_sql(table_name, column_names, references_table_name, references_column_names, options)
|
69
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} #{foreign_key_sql}"
|
70
|
+
end
|
71
|
+
|
72
|
+
# called directly by AT's bulk_change_table, for migration
|
73
|
+
# change_table :name, :bulk => true { ... }
|
74
|
+
def add_foreign_key_sql(table_name, column_names, references_table_name, references_column_names, options = {}) #:nodoc:
|
75
|
+
foreign_key = _build_foreign_key(table_name, column_names, references_table_name, references_column_names, options)
|
76
|
+
"ADD #{foreign_key.to_sql}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def _build_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {}) #:nodoc:
|
80
|
+
ForeignKeyDefinition.new(options[:name] || ForeignKeyDefinition.default_name(table_name, column_names), table_name, column_names, ::ActiveRecord::Migrator.proper_table_name(references_table_name), references_column_names, options[:on_update], options[:on_delete], options[:deferrable])
|
62
81
|
end
|
63
82
|
|
64
83
|
# Remove a foreign key constraint
|
65
84
|
#
|
85
|
+
# Arguments are the same as for add_foreign_key, or by name:
|
86
|
+
#
|
87
|
+
# remove_foreign_key table_name, column_names, references_table_name, references_column_names
|
88
|
+
# remove_foreign_key name: constraint_name
|
89
|
+
#
|
66
90
|
# (NOTE: Sqlite3 does not support altering a table to remove
|
67
91
|
# foreign-key constraints. If you're using Sqlite3, this method will
|
68
92
|
# raise an error.)
|
69
|
-
def remove_foreign_key(table_name,
|
70
|
-
|
93
|
+
def remove_foreign_key(table_name, *args)
|
94
|
+
case sql = remove_foreign_key_sql(table_name, *args)
|
95
|
+
when String then execute "ALTER TABLE #{quote_table_name(table_name)} #{sql}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def remove_foreign_key_sql(table_name, *args)
|
100
|
+
column_names, references_table_name, references_column_names, options = args
|
101
|
+
options ||= {}
|
102
|
+
foreign_key_name = case
|
103
|
+
when args.length == 1
|
104
|
+
case args[0]
|
105
|
+
when Hash then args[0][:name]
|
106
|
+
else args[0]
|
107
|
+
end
|
108
|
+
else
|
109
|
+
test_fk = _build_foreign_key(table_name, column_names, references_table_name, references_column_names, options)
|
110
|
+
if foreign_keys(table_name).detect { |fk| fk == test_fk }
|
111
|
+
test_fk.name
|
112
|
+
else
|
113
|
+
raise "SchemaPlus: no foreign key constraint found on #{table_name.inspect} matching #{args.inspect}" unless options[:if_exists]
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
foreign_key_name ? "DROP CONSTRAINT #{foreign_key_name}" : [] # hack -- return empty array rather than nil, so that result will disappear when caller flattens but doesn't compact
|
71
118
|
end
|
72
119
|
|
73
120
|
# Extends rails' drop_table to include these options:
|
@@ -82,6 +129,14 @@ module SchemaPlus
|
|
82
129
|
execute sql
|
83
130
|
end
|
84
131
|
|
132
|
+
# Extends rails' remove_index to include this options:
|
133
|
+
# :if_exists
|
134
|
+
def remove_index_with_schema_plus(table_name, options={})
|
135
|
+
return if options.delete(:if_exists) and not index_name_exists?(table_name, options[:name] || index_name(table_name, options), false)
|
136
|
+
options.delete(:column) if options[:name] and ::ActiveRecord::VERSION::MAJOR < 4
|
137
|
+
remove_index_without_schema_plus(table_name, options)
|
138
|
+
end
|
139
|
+
|
85
140
|
# called from individual adpaters, after renaming table from old
|
86
141
|
# name to
|
87
142
|
def rename_indexes_and_foreign_keys(oldname, newname) #:nodoc:
|
@@ -113,26 +168,73 @@ module SchemaPlus
|
|
113
168
|
false
|
114
169
|
end
|
115
170
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
171
|
+
module AddColumnOptions
|
172
|
+
def self.included(base) #:nodoc:
|
173
|
+
base.alias_method_chain :add_column_options!, :schema_plus
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_column_options_with_schema_plus!(sql, options)
|
177
|
+
if options_include_default?(options)
|
178
|
+
default = options[:default]
|
179
|
+
|
180
|
+
if default.is_a? Hash
|
181
|
+
value = default[:value]
|
182
|
+
expr = sql_for_function(default[:expr]) || default[:expr] if default[:expr]
|
183
|
+
else
|
184
|
+
value = default
|
185
|
+
expr = sql_for_function(default)
|
186
|
+
end
|
187
|
+
|
188
|
+
if expr
|
189
|
+
raise ArgumentError, "Invalid default expression" unless default_expr_valid?(expr)
|
190
|
+
sql << " DEFAULT #{expr}"
|
191
|
+
# must explicitly check for :null to allow change_column to work on migrations
|
192
|
+
if options[:null] == false
|
193
|
+
sql << " NOT NULL"
|
194
|
+
end
|
195
|
+
else
|
196
|
+
add_column_options_without_schema_plus!(sql, options.merge(default: value))
|
197
|
+
end
|
129
198
|
else
|
130
|
-
sql
|
199
|
+
add_column_options_without_schema_plus!(sql, options)
|
131
200
|
end
|
132
201
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
202
|
+
|
203
|
+
#####################################################################
|
204
|
+
#
|
205
|
+
# The functions below here are abstract; each subclass should
|
206
|
+
# define them all. Defining them here only for reference.
|
207
|
+
|
208
|
+
# (abstract) Return true if the passed expression can be used as a column
|
209
|
+
# default value. (For most databases the specific expression
|
210
|
+
# doesn't matter, and the adapter's function would return a
|
211
|
+
# constant true if default expressions are supported or false if
|
212
|
+
# they're not.)
|
213
|
+
def default_expr_valid?(expr) raise "Internal Error: Connection adapter didn't override abstract function"; end
|
214
|
+
|
215
|
+
# (abstract) Return SQL definition for a given canonical function_name symbol.
|
216
|
+
# Currently, the only function to support is :now, which should
|
217
|
+
# return a DATETIME object for the current time.
|
218
|
+
def sql_for_function(function_name) raise "Internal Error: Connection adapter didn't override abstract function"; end
|
219
|
+
end
|
220
|
+
|
221
|
+
module VisitTableDefinition
|
222
|
+
def self.included(base) #:nodoc:
|
223
|
+
base.alias_method_chain :visit_TableDefinition, :schema_plus
|
224
|
+
end
|
225
|
+
|
226
|
+
def visit_TableDefinition_with_schema_plus(o) #:nodoc:
|
227
|
+
create_sql = visit_TableDefinition_without_schema_plus(o)
|
228
|
+
last_chunk = ") #{o.options}"
|
229
|
+
|
230
|
+
unless create_sql.end_with?(last_chunk)
|
231
|
+
raise "Internal Error: Can't find '#{last_chunk}' at end of '#{create_sql}' - Rails internals have changed!"
|
232
|
+
end
|
233
|
+
|
234
|
+
unless o.foreign_keys.empty?
|
235
|
+
create_sql[create_sql.size - last_chunk.size, 0] = ', ' + o.foreign_keys.map(&:to_sql) * ', '
|
236
|
+
end
|
237
|
+
create_sql
|
136
238
|
end
|
137
239
|
end
|
138
240
|
|
@@ -141,7 +243,7 @@ module SchemaPlus
|
|
141
243
|
# The functions below here are abstract; each subclass should
|
142
244
|
# define them all. Defining them here only for reference.
|
143
245
|
#
|
144
|
-
|
246
|
+
|
145
247
|
# (abstract) Returns the names of all views, as an array of strings
|
146
248
|
def views(name = nil) raise "Internal Error: Connection adapter didn't override abstract function"; [] end
|
147
249
|
|
@@ -157,41 +259,6 @@ module SchemaPlus
|
|
157
259
|
# (abstract) Return the ForeignKeyDefinition objects for foreign key
|
158
260
|
# constraints defined on other tables that reference this table
|
159
261
|
def reverse_foreign_keys(table_name, name = nil) raise "Internal Error: Connection adapter didn't override abstract function"; [] end
|
160
|
-
|
161
|
-
# (abstract) Return true if the passed expression can be used as a column
|
162
|
-
# default value. (For most databases the specific expression
|
163
|
-
# doesn't matter, and the adapter's function would return a
|
164
|
-
# constant true if default expressions are supported or false if
|
165
|
-
# they're not.)
|
166
|
-
def default_expr_valid?(expr) raise "Internal Error: Connection adapter didn't override abstract function"; end
|
167
|
-
|
168
|
-
# (abstract) Return SQL definition for a given canonical function_name symbol.
|
169
|
-
# Currently, the only function to support is :now, which should
|
170
|
-
# return a DATETIME object for the current time.
|
171
|
-
def sql_for_function(function_name) raise "Internal Error: Connection adapter didn't override abstract function"; end
|
172
|
-
|
173
|
-
|
174
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i >= 4
|
175
|
-
module SchemaCreation
|
176
|
-
def self.included(base) #:nodoc:
|
177
|
-
base.alias_method_chain :visit_TableDefinition, :schema_plus
|
178
|
-
end
|
179
|
-
|
180
|
-
def visit_TableDefinition_with_schema_plus(o) #:nodoc:
|
181
|
-
create_sql = visit_TableDefinition_without_schema_plus(o)
|
182
|
-
last_chunk = ") #{o.options}"
|
183
|
-
|
184
|
-
unless create_sql.end_with?(last_chunk)
|
185
|
-
raise "Internal Error: Can't find '#{last_chunk}' at end of '#{create_sql}' - Rails internals have changed!"
|
186
|
-
end
|
187
|
-
|
188
|
-
unless o.foreign_keys.empty?
|
189
|
-
create_sql[create_sql.size - last_chunk.size, 0] = ', ' + o.foreign_keys.map(&:to_sql) * ', '
|
190
|
-
end
|
191
|
-
create_sql
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
262
|
end
|
196
263
|
end
|
197
264
|
end
|
@@ -49,9 +49,9 @@ module SchemaPlus
|
|
49
49
|
def initialize(name, table_name, column_names, references_table_name, references_column_names, on_update = nil, on_delete = nil, deferrable = nil)
|
50
50
|
@name = name
|
51
51
|
@table_name = unquote(table_name)
|
52
|
-
@column_names = unquote(column_names)
|
52
|
+
@column_names = unquote(Array.wrap(column_names))
|
53
53
|
@references_table_name = unquote(references_table_name)
|
54
|
-
@references_column_names = unquote(references_column_names)
|
54
|
+
@references_column_names = unquote(Array.wrap(references_column_names))
|
55
55
|
@on_update = on_update
|
56
56
|
@on_delete = on_delete
|
57
57
|
@deferrable = deferrable
|
@@ -124,6 +124,13 @@ module SchemaPlus
|
|
124
124
|
table_name.to_s.gsub(/[.]/, '_')
|
125
125
|
end
|
126
126
|
|
127
|
+
def ==(other) # note equality test ignores :name and options
|
128
|
+
[:table_name,
|
129
|
+
:column_names,
|
130
|
+
:references_table_name,
|
131
|
+
:references_column_names
|
132
|
+
].all? { |attr| self.send(attr) == other.send(attr) }
|
133
|
+
end
|
127
134
|
end
|
128
135
|
end
|
129
136
|
end
|
@@ -27,11 +27,15 @@ module SchemaPlus
|
|
27
27
|
tables_without_schema_plus(name, *args) - views(name)
|
28
28
|
end
|
29
29
|
|
30
|
-
def remove_column_with_schema_plus(table_name, column_name)
|
30
|
+
def remove_column_with_schema_plus(table_name, column_name, type=nil, options={})
|
31
31
|
foreign_keys(table_name).select { |foreign_key| foreign_key.column_names.include?(column_name.to_s) }.each do |foreign_key|
|
32
32
|
remove_foreign_key(table_name, foreign_key.name)
|
33
33
|
end
|
34
|
-
|
34
|
+
if ::ActiveRecord::VERSION::MAJOR.to_i >= 4
|
35
|
+
remove_column_without_schema_plus(table_name, column_name, type, options)
|
36
|
+
else
|
37
|
+
remove_column_without_schema_plus(table_name, column_name)
|
38
|
+
end
|
35
39
|
end
|
36
40
|
|
37
41
|
def rename_table_with_schema_plus(oldname, newname)
|
@@ -59,8 +63,22 @@ module SchemaPlus
|
|
59
63
|
super
|
60
64
|
end
|
61
65
|
|
62
|
-
def
|
63
|
-
|
66
|
+
def remove_index_sql(table_name, options)
|
67
|
+
return [] if options.delete(:if_exists) and not index_exists?(table_name, options)
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove_foreign_key_sql(table_name, *args)
|
72
|
+
case ret = super
|
73
|
+
when String then ret.sub(/DROP CONSTRAINT/, 'DROP FOREIGN KEY')
|
74
|
+
else ret
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove_foreign_key(table_name, *args)
|
79
|
+
case sql = remove_foreign_key_sql(table_name, *args)
|
80
|
+
when String then execute "ALTER TABLE #{quote_table_name(table_name)} #{sql}"
|
81
|
+
end
|
64
82
|
end
|
65
83
|
|
66
84
|
def foreign_keys(table_name, name = nil)
|
@@ -147,13 +165,15 @@ module SchemaPlus
|
|
147
165
|
sql
|
148
166
|
end
|
149
167
|
|
150
|
-
|
151
|
-
|
152
|
-
|
168
|
+
module AddColumnOptions
|
169
|
+
def default_expr_valid?(expr)
|
170
|
+
false # only the TIMESTAMP column accepts SQL column defaults and rails uses DATETIME
|
171
|
+
end
|
153
172
|
|
154
|
-
|
155
|
-
|
156
|
-
|
173
|
+
def sql_for_function(function)
|
174
|
+
case function
|
175
|
+
when :now then 'CURRENT_TIMESTAMP'
|
176
|
+
end
|
157
177
|
end
|
158
178
|
end
|
159
179
|
|