schema_plus 1.8.9 → 2.0.0.pre1
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.
- checksums.yaml +4 -4
- data/.gitignore +4 -4
- data/.travis.yml +1 -47
- data/CHANGELOG.md +0 -35
- data/README.md +73 -107
- data/Rakefile +7 -10
- data/TODO.md +51 -0
- data/gemfiles/Gemfile.base +2 -0
- data/lib/schema_column_plus.rb +7 -0
- data/lib/{schema_plus → schema_column_plus}/active_record/connection_adapters/column.rb +13 -11
- data/lib/schema_column_plus/middleware/model.rb +22 -0
- data/lib/schema_db_default.rb +13 -0
- data/lib/{schema_plus → schema_db_default}/active_record/attribute.rb +4 -4
- data/lib/schema_db_default/db_default.rb +17 -0
- data/lib/schema_db_default/middleware.rb +30 -0
- data/lib/schema_default_expr.rb +32 -0
- data/lib/schema_default_expr/active_record/connection_adapters/mysql_adapter.rb +17 -0
- data/lib/schema_default_expr/active_record/connection_adapters/postgresql_adapter.rb +18 -0
- data/lib/schema_default_expr/active_record/connection_adapters/sqlite3_adapter.rb +35 -0
- data/lib/schema_default_expr/middleware.rb +54 -0
- data/lib/schema_pg_enums.rb +6 -0
- data/lib/schema_pg_enums/active_record.rb +69 -0
- data/lib/schema_pg_enums/middleware.rb +23 -0
- data/lib/schema_plus.rb +17 -45
- data/lib/schema_plus/active_record/base.rb +6 -23
- data/lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb +80 -181
- data/lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb +78 -99
- data/lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb +34 -114
- data/lib/schema_plus/active_record/connection_adapters/postgresql_adapter.rb +16 -370
- data/lib/schema_plus/active_record/connection_adapters/schema_statements.rb +1 -67
- data/lib/schema_plus/active_record/connection_adapters/sqlite3_adapter.rb +18 -112
- data/lib/schema_plus/active_record/connection_adapters/table_definition.rb +14 -116
- data/lib/schema_plus/active_record/migration/command_recorder.rb +8 -59
- data/lib/schema_plus/middleware/dumper.rb +94 -0
- data/lib/schema_plus/middleware/migration.rb +167 -0
- data/lib/schema_plus/middleware/model.rb +17 -0
- data/lib/schema_plus/version.rb +1 -1
- data/lib/schema_plus_tables.rb +15 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/abstract_adapter.rb +20 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/mysql_adapter.rb +25 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/postgresql_adapter.rb +13 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/sqlite3_adapter.rb +12 -0
- data/lib/schema_views.rb +16 -0
- data/lib/schema_views/active_record/connection_adapters/abstract_adapter.rb +41 -0
- data/lib/schema_views/active_record/connection_adapters/mysql_adapter.rb +30 -0
- data/lib/schema_views/active_record/connection_adapters/postgresql_adapter.rb +31 -0
- data/lib/schema_views/active_record/connection_adapters/sqlite3_adapter.rb +18 -0
- data/lib/schema_views/middleware.rb +47 -0
- data/schema_dev.yml +1 -31
- data/schema_plus.gemspec +11 -9
- data/spec/foreign_key_definition_spec.rb +7 -7
- data/spec/foreign_key_spec.rb +63 -48
- data/spec/migration_spec.rb +58 -203
- data/spec/named_schemas_spec.rb +5 -88
- data/spec/{column_spec.rb → schema_column_plus/column_spec.rb} +26 -48
- data/spec/schema_db_default/column_spec.rb +58 -0
- data/spec/{column_default_spec.rb → schema_default_expr/column_default_spec.rb} +1 -2
- data/spec/schema_default_expr/schema_dumper_spec.rb +116 -0
- data/spec/schema_dumper_spec.rb +22 -327
- data/spec/{enum_spec.rb → schema_pg_enums/enum_spec.rb} +1 -1
- data/spec/schema_pg_enums/schema_dumper_spec.rb +37 -0
- data/spec/schema_views/named_schemas_spec.rb +97 -0
- data/spec/{views_spec.rb → schema_views/views_spec.rb} +1 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/support/matchers/reference.rb +11 -12
- metadata +104 -57
- data/gemfiles/rails-3.2/Gemfile.base +0 -3
- data/gemfiles/rails-3.2/Gemfile.mysql +0 -10
- data/gemfiles/rails-3.2/Gemfile.mysql2 +0 -10
- data/gemfiles/rails-3.2/Gemfile.postgresql +0 -10
- data/gemfiles/rails-3.2/Gemfile.sqlite3 +0 -10
- data/gemfiles/rails-4.0/Gemfile.base +0 -3
- data/gemfiles/rails-4.0/Gemfile.mysql2 +0 -10
- data/gemfiles/rails-4.0/Gemfile.postgresql +0 -10
- data/gemfiles/rails-4.0/Gemfile.sqlite3 +0 -10
- data/gemfiles/rails-4.1/Gemfile.base +0 -3
- data/gemfiles/rails-4.1/Gemfile.mysql2 +0 -10
- data/gemfiles/rails-4.1/Gemfile.postgresql +0 -10
- data/gemfiles/rails-4.1/Gemfile.sqlite3 +0 -10
- data/lib/schema_plus/active_record/column_options_handler.rb +0 -117
- data/lib/schema_plus/active_record/connection_adapters/index_definition.rb +0 -70
- data/lib/schema_plus/active_record/db_default.rb +0 -19
- data/lib/schema_plus/active_record/foreign_keys.rb +0 -137
- data/lib/schema_plus/active_record/schema_dumper.rb +0 -171
- data/lib/schema_plus/railtie.rb +0 -20
- data/spec/index_definition_spec.rb +0 -211
- data/spec/index_spec.rb +0 -249
@@ -4,18 +4,9 @@ module SchemaPlus::ActiveRecord::ConnectionAdapters
|
|
4
4
|
def self.included(base) #:nodoc:
|
5
5
|
base.class_eval do
|
6
6
|
alias_method_chain :create_table, :schema_plus
|
7
|
-
alias_method_chain :add_reference, :schema_plus unless ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
8
|
-
alias_method_chain :add_index_options, :schema_plus if "#{::ActiveRecord::VERSION::MAJOR}.#{::ActiveRecord::VERSION::MINOR}".to_r >= "4.2".to_r
|
9
|
-
include AddIndex
|
10
7
|
end
|
11
8
|
end
|
12
9
|
|
13
|
-
def add_reference_with_schema_plus(table_name, ref_name, options = {}) #:nodoc:
|
14
|
-
options[:references] = nil if options[:polymorphic]
|
15
|
-
options[:_index] = options.delete(:index) unless options[:polymorphic] # usurp index creation from AR
|
16
|
-
add_reference_without_schema_plus(table_name, ref_name, options)
|
17
|
-
end
|
18
|
-
|
19
10
|
##
|
20
11
|
# :method: create_table
|
21
12
|
#
|
@@ -33,68 +24,11 @@ module SchemaPlus::ActiveRecord::ConnectionAdapters
|
|
33
24
|
# override rails' :force to cascade
|
34
25
|
drop_table(table, if_exists: true, cascade: true) if options.delete(:force)
|
35
26
|
|
36
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
37
|
-
indexes = []
|
38
|
-
end
|
39
27
|
create_table_without_schema_plus(table, options) do |table_definition|
|
40
28
|
table_definition.schema_plus_config = SchemaPlus.config.merge(config_options)
|
41
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
42
|
-
table_definition.name = table
|
43
|
-
end
|
44
29
|
yield table_definition if block_given?
|
45
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
46
|
-
indexes = table_definition.indexes
|
47
|
-
end
|
48
|
-
end
|
49
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
50
|
-
indexes.each do |index|
|
51
|
-
add_index(table, index.columns, index.opts)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def add_index_options_with_schema_plus(table_name, column_name, options = {})
|
57
|
-
options = options.dup
|
58
|
-
with_columns = options.delete(:with) { |_| [] }
|
59
|
-
add_index_options_without_schema_plus(table_name, Array(column_name).concat(Array(with_columns).map(&:to_s)), options)
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.add_index_exception_handler(connection, table, columns, options, e) #:nodoc:
|
63
|
-
raise unless e.message.match(/["']([^"']+)["'].*already exists/)
|
64
|
-
name = $1
|
65
|
-
existing = connection.indexes(table).find{|i| i.name == name}
|
66
|
-
attempted = ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table, columns, options.merge(:name => name))
|
67
|
-
raise if attempted != existing
|
68
|
-
::ActiveRecord::Base.logger.warn "[schema_plus] Index name #{name.inspect}' on table #{table.inspect} already exists. Skipping."
|
69
|
-
end
|
70
|
-
|
71
|
-
module AddIndex
|
72
|
-
def self.included(base) #:nodoc:
|
73
|
-
base.class_eval do
|
74
|
-
alias_method_chain :add_index, :schema_plus
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
##
|
79
|
-
# :method: add_index
|
80
|
-
#
|
81
|
-
# SchemaPlus modifies SchemaStatements::add_index so that it ignores
|
82
|
-
# errors raised about add an index that already exists -- i.e. that has
|
83
|
-
# the same index name, same columns, and same options -- and writes a
|
84
|
-
# warning to the log. Some combinations of rails & DB adapter versions
|
85
|
-
# would log such a warning, others would raise an error; with
|
86
|
-
# SchemaPlus all versions log the warning and do not raise the error.
|
87
|
-
#
|
88
|
-
# (This avoids collisions between SchemaPlus's auto index behavior and
|
89
|
-
# legacy explicit add_index statements, for platforms that would raise
|
90
|
-
# an error.)
|
91
|
-
#
|
92
|
-
def add_index_with_schema_plus(table, columns, options={})
|
93
|
-
options.delete(:if_exists) if options # some callers explcitly pass options=nil
|
94
|
-
add_index_without_schema_plus(table, columns, options)
|
95
|
-
rescue => e
|
96
|
-
SchemaStatements.add_index_exception_handler(self, table, columns, options, e)
|
97
30
|
end
|
98
31
|
end
|
99
32
|
end
|
33
|
+
|
100
34
|
end
|
@@ -1,24 +1,6 @@
|
|
1
1
|
module SchemaPlus
|
2
2
|
module ActiveRecord
|
3
3
|
module ConnectionAdapters
|
4
|
-
module SQLiteColumn
|
5
|
-
def initialize(name, default, sql_type = nil, null = true)
|
6
|
-
if default =~ /DATETIME/
|
7
|
-
@default_expr = "(#{default})"
|
8
|
-
end
|
9
|
-
super(name, default, sql_type, null)
|
10
|
-
end
|
11
|
-
|
12
|
-
# AR 4.2 uses default_function rather than default_expr
|
13
|
-
def self.included(base)
|
14
|
-
base.alias_method_chain :default_function, :sqlite3 if base.instance_methods.include? :default_function
|
15
|
-
end
|
16
|
-
|
17
|
-
def default_function_with_sqlite3
|
18
|
-
@default_function ||= "(#{default})" if default =~ /DATETIME/
|
19
|
-
default_function_without_sqlite3
|
20
|
-
end
|
21
|
-
end
|
22
4
|
|
23
5
|
# SchemaPlus includes an Sqlite3 implementation of the AbstractAdapter
|
24
6
|
# extensions.
|
@@ -28,18 +10,7 @@ module SchemaPlus
|
|
28
10
|
|
29
11
|
def self.included(base)
|
30
12
|
base.class_eval do
|
31
|
-
alias_method_chain :indexes, :schema_plus
|
32
13
|
alias_method_chain :rename_table, :schema_plus
|
33
|
-
alias_method_chain :tables, :schema_plus
|
34
|
-
alias_method_chain :copy_table, :schema_plus
|
35
|
-
end
|
36
|
-
|
37
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
38
|
-
::ActiveRecord::ConnectionAdapters::SQLiteColumn.send(:include, SQLiteColumn) unless ::ActiveRecord::ConnectionAdapters::SQLiteColumn.include?(SQLiteColumn)
|
39
|
-
elsif defined? ::ActiveRecord::ConnectionAdapters::SQLite3Column
|
40
|
-
::ActiveRecord::ConnectionAdapters::SQLite3Column.send(:include, SQLiteColumn) unless ::ActiveRecord::ConnectionAdapters::SQLite3Column.include?(SQLiteColumn)
|
41
|
-
else # in ActiveRecord::VERSION 4.2 there's no SQLite3Column
|
42
|
-
::ActiveRecord::ConnectionAdapters::Column.send(:include, SQLiteColumn) unless ::ActiveRecord::ConnectionAdapters::Column.include?(SQLiteColumn)
|
43
14
|
end
|
44
15
|
end
|
45
16
|
|
@@ -48,57 +19,17 @@ module SchemaPlus
|
|
48
19
|
execute('PRAGMA FOREIGN_KEYS = ON')
|
49
20
|
end
|
50
21
|
|
51
|
-
def supports_partial_indexes? #:nodoc:
|
52
|
-
# unfortunately with the current setup there's no easy way to
|
53
|
-
# test multiple SQLite3 versions. Currently travis-ci uses
|
54
|
-
# SQLite3 version 3.7 but local development on OS X uses 3.8.
|
55
|
-
SQLite3.libversion >= 3008000
|
56
|
-
end
|
57
|
-
|
58
|
-
def indexes_with_schema_plus(table_name, name = nil)
|
59
|
-
indexes = indexes_without_schema_plus(table_name, name)
|
60
|
-
exec_query("SELECT name, sql FROM sqlite_master WHERE type = 'index'").map do |row|
|
61
|
-
sql = row['sql']
|
62
|
-
index = nil
|
63
|
-
getindex = -> { index ||= indexes.detect { |i| i.name == row['name'] } }
|
64
|
-
if (desc_columns = sql.scan(/['"`]?(\w+)['"`]? DESC\b/).flatten).any?
|
65
|
-
getindex.call()
|
66
|
-
index.orders = Hash[index.columns.map {|column| [column, desc_columns.include?(column) ? :desc : :asc]}]
|
67
|
-
end
|
68
|
-
if (conditions = sql.match(/\bWHERE\s+(.*)/i))
|
69
|
-
getindex.call()
|
70
|
-
index.conditions = conditions[1]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
indexes
|
74
|
-
end
|
75
|
-
|
76
|
-
def copy_table_with_schema_plus(*args, &block)
|
77
|
-
fk_override = { :auto_create => false, :auto_index => false }
|
78
|
-
save = Hash[fk_override.keys.collect{|key| [key, SchemaPlus.config.foreign_keys.send(key)]}]
|
79
|
-
begin
|
80
|
-
SchemaPlus.config.foreign_keys.update_attributes(fk_override)
|
81
|
-
copy_table_without_schema_plus(*args, &block)
|
82
|
-
ensure
|
83
|
-
SchemaPlus.config.foreign_keys.update_attributes(save)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
22
|
def rename_table_with_schema_plus(oldname, newname) #:nodoc:
|
88
23
|
rename_table_without_schema_plus(oldname, newname)
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
def add_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {})
|
93
|
-
raise NotImplementedError, "Sqlite3 does not support altering a table to add foreign key constraints (table #{table_name.inspect} column #{column_names.inspect})"
|
24
|
+
rename_foreign_keys(oldname, newname)
|
94
25
|
end
|
95
26
|
|
96
|
-
def
|
97
|
-
raise NotImplementedError, "Sqlite3 does not support altering a table to
|
27
|
+
def add_foreign_key(table_name, to_table, options = {})
|
28
|
+
raise NotImplementedError, "Sqlite3 does not support altering a table to add foreign key constraints (table #{table_name.inspect} to #{to_table.inspect})"
|
98
29
|
end
|
99
30
|
|
100
|
-
def
|
101
|
-
|
31
|
+
def remove_foreign_key(table_name, *args)
|
32
|
+
raise NotImplementedError, "Sqlite3 does not support altering a table to remove foreign key constraints (table #{table_name.inspect} constraint #{args.inspect})"
|
102
33
|
end
|
103
34
|
|
104
35
|
def foreign_keys(table_name, name = nil)
|
@@ -106,21 +37,7 @@ module SchemaPlus
|
|
106
37
|
end
|
107
38
|
|
108
39
|
def reverse_foreign_keys(table_name, name = nil)
|
109
|
-
get_foreign_keys(nil, name).select{|definition| definition.
|
110
|
-
end
|
111
|
-
|
112
|
-
def tables_with_schema_plus(*args)
|
113
|
-
# AR 4.2 explicitly looks for views or tables, but only for sqlite3. so take away the tables.
|
114
|
-
tables_without_schema_plus(*args) - views
|
115
|
-
end
|
116
|
-
|
117
|
-
def views(name = nil)
|
118
|
-
execute("SELECT name FROM sqlite_master WHERE type='view'", name).collect{|row| row["name"]}
|
119
|
-
end
|
120
|
-
|
121
|
-
def view_definition(view_name, name = nil)
|
122
|
-
sql = execute("SELECT sql FROM sqlite_master WHERE type='view' AND name=#{quote(view_name)}", name).collect{|row| row["sql"]}.first
|
123
|
-
sql.sub(/^CREATE VIEW \S* AS\s+/im, '') unless sql.nil?
|
40
|
+
get_foreign_keys(nil, name).select{|definition| definition.to_table == table_name}
|
124
41
|
end
|
125
42
|
|
126
43
|
protected
|
@@ -143,43 +60,32 @@ module SchemaPlus
|
|
143
60
|
|
144
61
|
foreign_keys = []
|
145
62
|
results.each do |row|
|
146
|
-
|
147
|
-
row["sql"].scan(re).each do |d0, name,
|
148
|
-
|
63
|
+
from_table = row["name"]
|
64
|
+
row["sql"].scan(re).each do |d0, name, columns, to_table, primary_keys, d1, on_update, d2, on_delete, deferrable, initially_deferred|
|
65
|
+
columns = columns.gsub(/`/, '').split(', ')
|
149
66
|
|
150
|
-
|
151
|
-
on_update = on_update
|
152
|
-
on_delete = on_delete
|
67
|
+
primary_keys = primary_keys.gsub(/[`"]/, '').split(', ')
|
68
|
+
on_update = ForeignKeyDefinition::ACTION_LOOKUP[on_update] || :no_action
|
69
|
+
on_delete = ForeignKeyDefinition::ACTION_LOOKUP[on_delete] || :no_action
|
153
70
|
deferrable = deferrable ? (initially_deferred ? :initially_deferred : true) : false
|
154
71
|
|
155
72
|
options = { :name => name,
|
156
73
|
:on_update => on_update,
|
157
74
|
:on_delete => on_delete,
|
158
|
-
:
|
159
|
-
:
|
75
|
+
:column => columns,
|
76
|
+
:primary_key => primary_keys,
|
160
77
|
:deferrable => deferrable }
|
161
78
|
|
162
|
-
foreign_keys << ForeignKeyDefinition.new(
|
163
|
-
|
164
|
-
|
79
|
+
foreign_keys << ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(
|
80
|
+
from_table,
|
81
|
+
to_table,
|
82
|
+
options)
|
165
83
|
end
|
166
84
|
end
|
167
85
|
|
168
86
|
foreign_keys
|
169
87
|
end
|
170
88
|
|
171
|
-
module AddColumnOptions
|
172
|
-
def default_expr_valid?(expr)
|
173
|
-
true # arbitrary sql is okay
|
174
|
-
end
|
175
|
-
|
176
|
-
def sql_for_function(function)
|
177
|
-
case function
|
178
|
-
when :now
|
179
|
-
"(DATETIME('now'))"
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
89
|
end
|
184
90
|
|
185
91
|
end
|
@@ -64,133 +64,31 @@ module SchemaPlus::ActiveRecord::ConnectionAdapters
|
|
64
64
|
# end
|
65
65
|
#
|
66
66
|
module TableDefinition
|
67
|
-
include SchemaPlus::ActiveRecord::ColumnOptionsHandler
|
68
67
|
|
69
68
|
attr_accessor :schema_plus_config #:nodoc:
|
70
|
-
attr_reader :foreign_keys #:nodoc:
|
71
69
|
|
72
|
-
def
|
73
|
-
|
74
|
-
alias_method_chain :initialize, :schema_plus
|
75
|
-
alias_method_chain :column, :schema_plus
|
76
|
-
alias_method_chain :references, :schema_plus
|
77
|
-
alias_method_chain :belongs_to, :schema_plus
|
78
|
-
alias_method_chain :primary_key, :schema_plus
|
79
|
-
|
80
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
81
|
-
attr_accessor :name
|
82
|
-
attr_accessor :indexes
|
83
|
-
alias_method_chain :to_sql, :schema_plus
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def initialize_with_schema_plus(*args) #:nodoc:
|
89
|
-
initialize_without_schema_plus(*args)
|
90
|
-
@foreign_keys = []
|
91
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
92
|
-
@indexes = []
|
93
|
-
end
|
70
|
+
def foreign_keys
|
71
|
+
@foreign_keys ||= []
|
94
72
|
end
|
95
73
|
|
96
|
-
|
97
|
-
def primary_key_with_schema_plus(name, options = {}) #:nodoc:
|
98
|
-
column(name, :primary_key, options)
|
99
|
-
end
|
100
|
-
else
|
101
|
-
def primary_key_with_schema_plus(name, type = :primary_key, options = {}) #:nodoc:
|
102
|
-
column(name, type, options.merge(:primary_key => true))
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
# need detect :polymorphic at this level, because rails strips it out
|
108
|
-
# before calling #column (twice, once for _id and once for _type)
|
109
|
-
def references_with_schema_plus(*args) #:nodoc:
|
74
|
+
def foreign_key(*args) # (column_names, to_table, primary_key=nil, options=nil)
|
110
75
|
options = args.extract_options!
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
def belongs_to_with_schema_plus(*args) #:nodoc:
|
121
|
-
options = args.extract_options!
|
122
|
-
options[:references] = nil if options[:polymorphic]
|
123
|
-
schema_plus_normalize_column_options(options)
|
124
|
-
options[:_index] = options.delete(:index) unless options[:polymorphic] # usurp index creation from AR
|
125
|
-
args << options
|
126
|
-
belongs_to_without_schema_plus(*args)
|
127
|
-
end
|
128
|
-
|
129
|
-
def column_with_schema_plus(name, type, options = {}) #:nodoc:
|
130
|
-
schema_plus_normalize_column_options(options)
|
131
|
-
# prevent AR from seeing :index => false as a request for an index
|
132
|
-
if noindex = options[:index] == false
|
133
|
-
options.delete(:index)
|
76
|
+
case args.length
|
77
|
+
when 2
|
78
|
+
column_names, to_table = args
|
79
|
+
when 3
|
80
|
+
ActiveSupport::Deprecation.warn "positional arg for foreign primary key is deprecated, use :primary_key option instead"
|
81
|
+
column_names, to_table, primary_key = args
|
82
|
+
options.merge(:primary_key => primary_key)
|
83
|
+
else
|
84
|
+
raise ArgumentError, "wrong number of arguments (#{args.length}) for foreign_key(column_names, table_name, options)"
|
134
85
|
end
|
135
|
-
column_without_schema_plus(name, type, options)
|
136
|
-
options[:index] = false if noindex
|
137
|
-
schema_plus_handle_column_options(self.name, name, options, :config => schema_plus_config)
|
138
|
-
self
|
139
|
-
end
|
140
|
-
|
141
|
-
def to_sql_with_schema_plus #:nodoc:
|
142
|
-
sql = to_sql_without_schema_plus
|
143
|
-
sql << ', ' << @foreign_keys.map(&:to_sql) * ', ' unless @foreign_keys.empty?
|
144
|
-
sql
|
145
|
-
end
|
146
86
|
|
147
|
-
|
148
|
-
if ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
149
|
-
def index(column_name, options={})
|
150
|
-
@indexes << ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(self.name, column_name, options)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def foreign_key(column_names, references_table_name, references_column_names, options = {})
|
155
|
-
options.merge!(:column_names => column_names, :references_column_names => references_column_names)
|
87
|
+
options.merge!(:column => column_names)
|
156
88
|
options.reverse_merge!(:name => ForeignKeyDefinition.default_name(self.name, column_names))
|
157
|
-
|
89
|
+
foreign_keys << ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(self.name, AbstractAdapter.proper_table_name(to_table), options)
|
158
90
|
self
|
159
91
|
end
|
160
92
|
|
161
|
-
protected
|
162
|
-
# The only purpose of that method is to provide a consistent intefrace
|
163
|
-
# for ColumnOptionsHandler. First argument (table name) is ignored.
|
164
|
-
def add_index(_, *args) #:nodoc:
|
165
|
-
index(*args)
|
166
|
-
end
|
167
|
-
|
168
|
-
# The only purpose of that method is to provide a consistent intefrace
|
169
|
-
# for ColumnOptionsHandler. First argument (table name) is ignored.
|
170
|
-
def add_foreign_key(_, *args) #:nodoc:
|
171
|
-
foreign_key(*args)
|
172
|
-
end
|
173
|
-
|
174
|
-
# This is a deliberately empty stub. The reason for it is that
|
175
|
-
# ColumnOptionsHandler is used for changes as well as for table
|
176
|
-
# definitions, and in the case of changes, previously existing foreign
|
177
|
-
# keys sometimes need to be removed. but in the case here, that of
|
178
|
-
# table definitions, the only reason a foreign key would exist is
|
179
|
-
# because we're redefining a table that already exists (via :force =>
|
180
|
-
# true). in which case the foreign key will get dropped when the
|
181
|
-
# drop_table gets emitted, so no need to do it immediately. (and for
|
182
|
-
# sqlite3, attempting to do it immediately would raise an error).
|
183
|
-
def remove_foreign_key(_, *args) #:nodoc:
|
184
|
-
end
|
185
|
-
|
186
|
-
# This is a deliberately empty stub. The reason for it is that
|
187
|
-
# ColumnOptionsHandler will remove a previous index when changing a
|
188
|
-
# column. But we don't do column changes within table definitions.
|
189
|
-
# Presumably will be called with :if_exists true. If not, will raise
|
190
|
-
# an error.
|
191
|
-
def remove_index(_, options)
|
192
|
-
raise "InternalError: remove_index called in a table definition" unless options[:if_exists]
|
193
|
-
end
|
194
|
-
|
195
93
|
end
|
196
94
|
end
|
@@ -2,26 +2,16 @@ module SchemaPlus
|
|
2
2
|
module ActiveRecord
|
3
3
|
module Migration
|
4
4
|
module CommandRecorder
|
5
|
-
include SchemaPlus::ActiveRecord::ColumnOptionsHandler
|
6
5
|
|
7
6
|
attr_accessor :schema_plus_config #:nodoc:
|
8
7
|
|
9
8
|
def self.included(base) #:nodoc:
|
10
9
|
base.class_eval do
|
11
|
-
alias_method_chain :
|
12
|
-
alias_method_chain :add_reference, :schema_plus unless ::ActiveRecord::VERSION::MAJOR.to_i < 4
|
10
|
+
alias_method_chain :add_reference, :schema_plus
|
13
11
|
alias_method_chain :invert_add_index, :schema_plus
|
14
|
-
alias_method_chain :invert_add_foreign_key, :schema_plus if "#{::ActiveRecord::VERSION::MAJOR}.#{::ActiveRecord::VERSION::MINOR}".to_r >= "4.2".to_r
|
15
12
|
end
|
16
13
|
end
|
17
14
|
|
18
|
-
def add_column_with_schema_plus(table_name, name, type, options = {}) #:nodoc:
|
19
|
-
schema_plus_normalize_column_options(options)
|
20
|
-
add_column_without_schema_plus(table_name, name, type, options)
|
21
|
-
revertable_schema_plus_handle_column_options(table_name, name, options, :config => schema_plus_config)
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
15
|
# seems like this is fixing a rails bug:
|
26
16
|
# change_table foo, :bulk => true { |t| t.references :bar }
|
27
17
|
# results in an 'unknown method :add_reference_sql' (with mysql2)
|
@@ -29,63 +19,22 @@ module SchemaPlus
|
|
29
19
|
# should track it down separately and submit a patch/fix to rails
|
30
20
|
#
|
31
21
|
def add_reference_with_schema_plus(table_name, ref_name, options = {}) #:nodoc:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
polymorphic = options.delete(:polymorphic)
|
40
|
-
index_options = options.delete(:index)
|
41
|
-
add_column(table_name, "#{ref_name}_id", :integer, options)
|
42
|
-
add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
|
43
|
-
add_index(table_name, polymorphic ? %w[id type].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
|
44
|
-
end
|
22
|
+
polymorphic = options.delete(:polymorphic)
|
23
|
+
options[:references] = nil if polymorphic
|
24
|
+
# ugh. copying and pasting code from ::ActiveRecord::ConnectionAdapters::SchemaStatements#add_reference
|
25
|
+
index_options = options.delete(:index)
|
26
|
+
add_column(table_name, "#{ref_name}_id", :integer, options)
|
27
|
+
add_column(table_name, "#{ref_name}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) if polymorphic
|
28
|
+
add_index(table_name, polymorphic ? %w[id type].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options
|
45
29
|
|
46
30
|
self
|
47
31
|
end
|
48
32
|
|
49
|
-
if ::ActiveRecord::VERSION::MAJOR >= 4
|
50
|
-
def revertable_schema_plus_handle_column_options(table_name, name, options, config)
|
51
|
-
length = commands.length
|
52
|
-
schema_plus_handle_column_options(table_name, name, options, config)
|
53
|
-
if reverting
|
54
|
-
rev = []
|
55
|
-
while commands.length > length
|
56
|
-
cmd = commands.pop
|
57
|
-
rev.unshift cmd unless cmd[0].to_s =~ /^add_/
|
58
|
-
end
|
59
|
-
commands.concat rev
|
60
|
-
end
|
61
|
-
end
|
62
|
-
else
|
63
|
-
alias :revertable_schema_plus_handle_column_options :schema_plus_handle_column_options
|
64
|
-
end
|
65
|
-
|
66
|
-
def add_foreign_key(*args)
|
67
|
-
record(:add_foreign_key, args)
|
68
|
-
end
|
69
|
-
|
70
|
-
def invert_add_foreign_key(args)
|
71
|
-
table_name, column_names, references_table_name, references_column_names, options = args
|
72
|
-
[:remove_foreign_key, [table_name, column_names, references_table_name, references_column_names, (options||{}).merge(if_exists: true)]]
|
73
|
-
end
|
74
|
-
alias :invert_add_foreign_key_with_schema_plus :invert_add_foreign_key
|
75
|
-
|
76
33
|
def invert_add_index_with_schema_plus(args)
|
77
34
|
table, columns, options = *args
|
78
35
|
[:remove_index, [table, (options||{}).merge(column: columns, if_exists: true)]]
|
79
36
|
end
|
80
37
|
|
81
|
-
def remove_foreign_key(*args)
|
82
|
-
record(:remove_foreign_key, args)
|
83
|
-
end
|
84
|
-
|
85
|
-
def invert_remove_foreign_key(args)
|
86
|
-
[:add_foreign_key, args]
|
87
|
-
end
|
88
|
-
|
89
38
|
end
|
90
39
|
end
|
91
40
|
end
|