schema_plus 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +25 -0
  2. data/Gemfile +3 -0
  3. data/MIT-LICENSE +25 -0
  4. data/README.rdoc +147 -0
  5. data/Rakefile +70 -0
  6. data/init.rb +1 -0
  7. data/lib/schema_plus/active_record/associations.rb +211 -0
  8. data/lib/schema_plus/active_record/base.rb +81 -0
  9. data/lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb +96 -0
  10. data/lib/schema_plus/active_record/connection_adapters/column.rb +55 -0
  11. data/lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb +115 -0
  12. data/lib/schema_plus/active_record/connection_adapters/index_definition.rb +51 -0
  13. data/lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb +111 -0
  14. data/lib/schema_plus/active_record/connection_adapters/postgresql_adapter.rb +163 -0
  15. data/lib/schema_plus/active_record/connection_adapters/schema_statements.rb +39 -0
  16. data/lib/schema_plus/active_record/connection_adapters/sqlite3_adapter.rb +78 -0
  17. data/lib/schema_plus/active_record/connection_adapters/table_definition.rb +130 -0
  18. data/lib/schema_plus/active_record/migration.rb +220 -0
  19. data/lib/schema_plus/active_record/schema.rb +27 -0
  20. data/lib/schema_plus/active_record/schema_dumper.rb +122 -0
  21. data/lib/schema_plus/active_record/validations.rb +139 -0
  22. data/lib/schema_plus/railtie.rb +12 -0
  23. data/lib/schema_plus/version.rb +3 -0
  24. data/lib/schema_plus.rb +248 -0
  25. data/schema_plus.gemspec +37 -0
  26. data/schema_plus.gemspec.rails3.0 +36 -0
  27. data/schema_plus.gemspec.rails3.1 +36 -0
  28. data/spec/association_spec.rb +529 -0
  29. data/spec/connections/mysql/connection.rb +18 -0
  30. data/spec/connections/mysql2/connection.rb +18 -0
  31. data/spec/connections/postgresql/connection.rb +15 -0
  32. data/spec/connections/sqlite3/connection.rb +14 -0
  33. data/spec/foreign_key_definition_spec.rb +23 -0
  34. data/spec/foreign_key_spec.rb +142 -0
  35. data/spec/index_definition_spec.rb +139 -0
  36. data/spec/index_spec.rb +71 -0
  37. data/spec/migration_spec.rb +405 -0
  38. data/spec/models/comment.rb +2 -0
  39. data/spec/models/post.rb +2 -0
  40. data/spec/models/user.rb +2 -0
  41. data/spec/references_spec.rb +78 -0
  42. data/spec/schema/auto_schema.rb +23 -0
  43. data/spec/schema/core_schema.rb +21 -0
  44. data/spec/schema_dumper_spec.rb +167 -0
  45. data/spec/schema_spec.rb +71 -0
  46. data/spec/spec_helper.rb +59 -0
  47. data/spec/support/extensions/active_model.rb +13 -0
  48. data/spec/support/helpers.rb +16 -0
  49. data/spec/support/matchers/automatic_foreign_key_matchers.rb +2 -0
  50. data/spec/support/matchers/have_index.rb +52 -0
  51. data/spec/support/matchers/reference.rb +66 -0
  52. data/spec/support/reference.rb +66 -0
  53. data/spec/validations_spec.rb +294 -0
  54. data/spec/views_spec.rb +140 -0
  55. metadata +269 -0
@@ -0,0 +1,27 @@
1
+ module SchemaPlus
2
+ module ActiveRecord
3
+ module Schema #:nodoc: all
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def self.extended(base)
10
+ class << base
11
+ attr_accessor :defining
12
+ alias :defining? :defining
13
+
14
+ alias_method_chain :define, :schema_plus
15
+ end
16
+ end
17
+
18
+ def define_with_schema_plus(info={}, &block)
19
+ self.defining = true
20
+ define_without_schema_plus(info, &block)
21
+ ensure
22
+ self.defining = false
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,122 @@
1
+ require 'tsort'
2
+
3
+ module SchemaPlus
4
+ module ActiveRecord
5
+
6
+ # SchemaPlus modifies ActiveRecord's schema dumper to include foreign
7
+ # key constraints and views.
8
+ #
9
+ # Additionally, index and foreign key constraint definitions are dumped
10
+ # inline in the create_table block. (This is done for elegance, but
11
+ # also because Sqlite3 does not allow foreign key constraints to be
12
+ # added to a table after it has been defined.)
13
+ #
14
+ # The tables and views are dumped in alphabetical order, subject to
15
+ # topological sort constraints that a table must be dumped before any
16
+ # view that references it or table that has a foreign key constaint to
17
+ # it.
18
+ #
19
+ module SchemaDumper
20
+
21
+ include TSort
22
+
23
+ def self.included(base) #:nodoc:
24
+ base.class_eval do
25
+ private
26
+ alias_method_chain :table, :schema_plus
27
+ alias_method_chain :tables, :schema_plus
28
+ alias_method_chain :indexes, :schema_plus
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def tables_with_schema_plus(stream) #:nodoc:
35
+ @table_dumps = {}
36
+ @re_view_referent = %r{(?:(?i)FROM|JOIN) \S*\b(#{(@connection.tables + @connection.views).join('|')})\b}
37
+ begin
38
+ tables_without_schema_plus(nil)
39
+
40
+ @connection.views.each do |view_name|
41
+ definition = @connection.view_definition(view_name)
42
+ @table_dumps[view_name] = " create_view #{view_name.inspect}, #{definition.inspect}\n"
43
+ end
44
+
45
+ tsort().each do |table|
46
+ stream.print @table_dumps[table]
47
+ end
48
+
49
+ ensure
50
+ @table_dumps = nil
51
+ end
52
+ end
53
+
54
+ def tsort_each_node(&block) #:nodoc:
55
+ @table_dumps.keys.sort.each(&block)
56
+ end
57
+
58
+ def tsort_each_child(table, &block) #:nodoc:
59
+ references = if @connection.views.include?(table)
60
+ @connection.view_definition(table).scan(@re_view_referent).flatten
61
+ else
62
+ @connection.foreign_keys(table).collect(&:references_table_name)
63
+ end
64
+ references.sort.uniq.each(&block)
65
+ end
66
+
67
+ def table_with_schema_plus(table, ignore) #:nodoc:
68
+
69
+ stream = StringIO.new
70
+ table_without_schema_plus(table, stream)
71
+ stream.rewind
72
+ table_dump = stream.read
73
+
74
+ if i = (table_dump =~ /^\s*[e]nd\s*$/)
75
+ stream = StringIO.new
76
+ dump_indexes(table, stream)
77
+ dump_foreign_keys(table, stream)
78
+ stream.rewind
79
+ table_dump.insert i, stream.read
80
+ end
81
+
82
+ @table_dumps[table] = table_dump
83
+ end
84
+
85
+ def indexes_with_schema_plus(table, stream) #:nodoc:
86
+ # do nothing. we've already taken care of indexes as part of
87
+ # dumping the tables
88
+ end
89
+
90
+ def dump_indexes(table, stream) #:nodoc:
91
+ indexes = @connection.indexes(table)
92
+ indexes.each do |index|
93
+ stream.print " t.index"
94
+ unless index.columns.blank?
95
+ stream.print " #{index.columns.inspect}, :name => #{index.name.inspect}"
96
+ stream.print ", :unique => true" if index.unique
97
+ stream.print ", :kind => \"#{index.kind}\"" unless index.kind.blank?
98
+ stream.print ", :case_sensitive => false" unless index.case_sensitive?
99
+ stream.print ", :conditions => #{index.conditions.inspect}" unless index.conditions.blank?
100
+ index_lengths = index.lengths.compact if index.lengths.is_a?(Array)
101
+ stream.print ", :length => #{Hash[*index.columns.zip(index.lengths).flatten].inspect}" if index_lengths.present?
102
+ else
103
+ stream.print " :name => #{index.name.inspect}"
104
+ stream.print ", :kind => \"#{index.kind}\"" unless index.kind.blank?
105
+ stream.print ", :expression => #{index.expression.inspect}"
106
+ end
107
+
108
+ stream.puts
109
+ end
110
+ end
111
+
112
+ def dump_foreign_keys(table, stream) #:nodoc:
113
+ foreign_keys = @connection.foreign_keys(table)
114
+ foreign_keys.each do |foreign_key|
115
+ stream.print " "
116
+ stream.puts foreign_key.to_dump
117
+ end
118
+ end
119
+
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,139 @@
1
+ module SchemaPlus
2
+ module ActiveRecord
3
+ module Validations
4
+
5
+ def inherited(klass) #:nodoc:
6
+ if self == ::ActiveRecord::Base
7
+ klass.instance_eval do
8
+
9
+ # create a callback to load the validations before validation
10
+ # happens. the callback deletes itself after use (just to
11
+ # eliminate the callback overhead).
12
+ before_validation :load_schema_validations
13
+ private
14
+ define_method :load_schema_validations do
15
+ self.class.send :load_schema_validations
16
+ self.class.skip_callback :validation, :before, :load_schema_validations
17
+ end
18
+ end
19
+ end
20
+ super
21
+ end
22
+
23
+ # Adds schema-based validations to model.
24
+ # Attributes as well as associations are validated.
25
+ # For instance if there is column
26
+ #
27
+ # <code>email NOT NULL</code>
28
+ #
29
+ # defined at database-level it will be translated to
30
+ #
31
+ # <code>validates_presence_of :email</code>
32
+ #
33
+ # If there is an association named <tt>user</tt>
34
+ # based on <tt>user_id NOT NULL</tt> it will be translated to
35
+ #
36
+ # <code>validates_presence_of :user</code>
37
+ #
38
+ # Note it uses the name of association (user) not the column name (user_id).
39
+ # Only <tt>belongs_to</tt> associations are validated.
40
+ #
41
+ # This accepts following options:
42
+ # * :only - auto-validate only given attributes
43
+ # * :except - auto-validate all but given attributes
44
+ #
45
+ def schema_plus(*) #:nodoc:
46
+ super
47
+ load_schema_validations
48
+ end
49
+
50
+ private
51
+
52
+ def load_schema_validations #:nodoc:
53
+ # Don't bother if: it's already been loaded; the class is abstract; not a base class; or the table doesn't exist
54
+ return unless create_schema_validations?
55
+
56
+ load_column_validations
57
+ load_association_validations
58
+ @schema_validations_loaded = true
59
+ end
60
+
61
+ def load_column_validations #:nodoc:
62
+ content_columns.each do |column|
63
+ name = column.name.to_sym
64
+
65
+ # Data-type validation
66
+ if column.type == :integer
67
+ validate_logged :validates_numericality_of, name, :allow_nil => true, :only_integer => true
68
+ elsif column.number?
69
+ validate_logged :validates_numericality_of, name, :allow_nil => true
70
+ elsif column.text? && column.limit
71
+ validate_logged :validates_length_of, name, :allow_nil => true, :maximum => column.limit
72
+ end
73
+
74
+ # NOT NULL constraints
75
+ if column.required_on
76
+ if column.type == :boolean
77
+ validate_logged :validates_inclusion_of, name, :in => [true, false], :message => :blank
78
+ else
79
+ validate_logged :validates_presence_of, name
80
+ end
81
+ end
82
+
83
+ # UNIQUE constraints
84
+ add_uniqueness_validation(column) if column.unique?
85
+ end
86
+ end
87
+
88
+ def load_association_validations #:nodoc:
89
+ reflect_on_all_associations(:belongs_to).each do |association|
90
+ # :primary_key_name was deprecated (noisily) in rails 3.1
91
+ foreign_key_method = (association.respond_to? :foreign_key) ? :foreign_key : :primary_key_name
92
+ column = columns_hash[association.send(foreign_key_method).to_s]
93
+ next unless column
94
+
95
+ # NOT NULL constraints
96
+ validate_logged :validates_presence_of, association.name if column.required_on
97
+
98
+ # UNIQUE constraints
99
+ add_uniqueness_validation(column) if column.unique?
100
+ end
101
+ end
102
+
103
+ def add_uniqueness_validation(column) #:nodoc:
104
+ scope = column.unique_scope.map(&:to_sym)
105
+ condition = :"#{column.name}_changed?"
106
+ name = column.name.to_sym
107
+ validate_logged :validates_uniqueness_of, name, :scope => scope, :allow_nil => true, :if => condition
108
+ end
109
+
110
+ def create_schema_validations? #:nodoc:
111
+ schema_plus_config.validations.auto_create? && !(@schema_validations_loaded || abstract_class? || name.blank? || !table_exists?)
112
+ end
113
+
114
+ def validate_logged(method, arg, opts={}) #:nodoc:
115
+ if _filter_validation(method, arg)
116
+ msg = "SchemaPlus validations: #{self.name}.#{method} #{arg.inspect}"
117
+ msg += ", #{opts.inspect[1...-1]}" if opts.any?
118
+ logger.info msg
119
+ send method, arg, opts
120
+ end
121
+ end
122
+
123
+ def _filter_validation(macro, name) #:nodoc:
124
+ config = schema_plus_config.validations
125
+ types = [macro]
126
+ if match = macro.to_s.match(/^validates_(.*)_of$/)
127
+ types << match[1].to_sym
128
+ end
129
+ return false if config.only and not Array.wrap(config.only).include?(name)
130
+ return false if config.except and Array.wrap(config.except).include?(name)
131
+ return false if config.only_type and not (Array.wrap(config.only_type) & types).any?
132
+ return false if config.except_type and (Array.wrap(config.except_type) & types).any?
133
+ return true
134
+ end
135
+
136
+ end
137
+
138
+ end
139
+ end
@@ -0,0 +1,12 @@
1
+ module SchemaPlus
2
+ class Railtie < Rails::Railtie #:nodoc:
3
+ config.before_initialize do
4
+ SchemaPlus.insert_connection_adapters
5
+ end
6
+
7
+ initializer 'schema_plus.insert', :after => :load_config_initializers do
8
+ SchemaPlus.insert
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module SchemaPlus
2
+ VERSION = "0.1.0.pre1"
3
+ end
@@ -0,0 +1,248 @@
1
+ require 'valuable'
2
+
3
+ require 'schema_plus/version'
4
+ require 'schema_plus/active_record/base'
5
+ require 'schema_plus/active_record/migration'
6
+ require 'schema_plus/active_record/connection_adapters/table_definition'
7
+ require 'schema_plus/active_record/connection_adapters/schema_statements'
8
+ require 'schema_plus/active_record/schema'
9
+ require 'schema_plus/active_record/schema_dumper'
10
+ require 'schema_plus/active_record/connection_adapters/abstract_adapter'
11
+ require 'schema_plus/active_record/connection_adapters/column'
12
+ require 'schema_plus/active_record/connection_adapters/foreign_key_definition'
13
+ require 'schema_plus/active_record/connection_adapters/index_definition'
14
+ require 'schema_plus/active_record/associations'
15
+ require 'schema_plus/railtie' if defined?(Rails)
16
+
17
+ module SchemaPlus
18
+ module ActiveRecord
19
+
20
+ autoload :Validations, 'schema_plus/active_record/validations'
21
+
22
+ module ConnectionAdapters
23
+ autoload :MysqlAdapter, 'schema_plus/active_record/connection_adapters/mysql_adapter'
24
+ autoload :PostgresqlAdapter, 'schema_plus/active_record/connection_adapters/postgresql_adapter'
25
+ autoload :Sqlite3Adapter, 'schema_plus/active_record/connection_adapters/sqlite3_adapter'
26
+ end
27
+ end
28
+
29
+ # This global configuation options for SchmeaPlus.
30
+ # Set them in +config/initializers/schema_plus.rb+ using:
31
+ #
32
+ # SchemaPlus.setup do |config|
33
+ # ...
34
+ # end
35
+ #
36
+ # The options are grouped into subsets based on area of functionality.
37
+ # See Config::ForeignKeys, Config::Associations, Config::Validations
38
+ #
39
+ class Config < Valuable
40
+
41
+ # This set of configuration options control SchemaPlus's foreign key
42
+ # constraint behavior. Set them in
43
+ # +config/initializers/schema_plus.rb+ using:
44
+ #
45
+ # SchemaPlus.setup do |config|
46
+ # config.foreign_keys.auto_create = ...
47
+ # end
48
+ #
49
+ class ForeignKeys < Valuable
50
+ ##
51
+ # :attr_accessor: auto_create
52
+ #
53
+ # Whether to automatically create foreign key constraints for columns
54
+ # suffixed with +_id+. Boolean, default is +true+.
55
+ has_value :auto_create, :klass => :boolean, :default => true
56
+
57
+ ##
58
+ # :attr_accessor: auto_index
59
+ #
60
+ # Whether to automatically create indexes when creating foreign key constraints for columns.
61
+ # Boolean, default is +true+.
62
+ has_value :auto_index, :klass => :boolean, :default => true
63
+
64
+ ##
65
+ # :attr_accessor: on_update
66
+ #
67
+ # The default value for +:on_update+ when creating foreign key
68
+ # constraints for columns. Valid values are as described in
69
+ # ForeignKeyDefinition, or +nil+ to let the database connection use
70
+ # its own default. Default is +nil+.
71
+ has_value :on_update
72
+
73
+ ##
74
+ # :attr_accessor: on_delete
75
+ #
76
+ # The default value for +:on_delete+ when creating foreign key
77
+ # constraints for columns. Valid values are as described in
78
+ # ForeignKeyDefinition, or +nil+ to let the database connection use
79
+ # its own default. Default is +nil+.
80
+ has_value :on_delete
81
+ end
82
+ has_value :foreign_keys, :klass => ForeignKeys, :default => ForeignKeys.new
83
+
84
+ # This set of configuration options control SchemaPlus's automatic
85
+ # association behavior. Set them in
86
+ # +config/initializers/schema_plus.rb+ using:
87
+ #
88
+ # SchemaPlus.setup do |config|
89
+ # config.associations.auto_create = ...
90
+ # end
91
+ #
92
+ class Associations < Valuable
93
+
94
+ ##
95
+ # :attr_accessor: auto_create
96
+ #
97
+ # Whether to automatically create associations based on foreign keys.
98
+ # Boolean, default is +true+.
99
+ has_value :auto_create, :klass => :boolean, :default => true
100
+
101
+ ##
102
+ # :attr_accessor: concise_names
103
+ #
104
+ # Whether to use concise naming (strip out common prefixes from class names).
105
+ # Boolean, default is +true+.
106
+ has_value :concise_names, :klass => :boolean, :default => true
107
+
108
+ ##
109
+ # :attr_accessor: except
110
+ #
111
+ # List of association names to exclude from automatic creation.
112
+ # Value is a single name, an array of names, or +nil+. Default is +nil+.
113
+ has_value :except, :default => nil
114
+
115
+ ##
116
+ # :attr_accessor: only
117
+ #
118
+ # List of association names to include in automatic creation.
119
+ # Value is a single name, and array of names, or +nil+. Default is +nil+.
120
+ has_value :only, :default => nil
121
+
122
+ ##
123
+ # :attr_accessor: except_type
124
+ #
125
+ # List of association types to exclude from automatic creation.
126
+ # Value is one or an array of +:belongs_to+, +:has_many+, +:has_one+, and/or
127
+ # +:has_and_belongs_to_many+, or +nil+. Default is +nil+.
128
+ has_value :except_type, :default => nil
129
+
130
+ ##
131
+ # :attr_accessor: only_type
132
+ #
133
+ # List of association types to include from automatic creation.
134
+ # Value is one or an array of +:belongs_to+, +:has_many+, +:has_one+, and/or
135
+ # +:has_and_belongs_to_many+, or +nil+. Default is +nil+.
136
+ has_value :only_type, :default => nil
137
+
138
+ end
139
+ has_value :associations, :klass => Associations, :default => Associations.new
140
+
141
+ # This set of configuration options control SchemaPlus's automatic
142
+ # validations behavior. Set them in
143
+ # +config/initializers/schema_plus.rb+ using:
144
+ #
145
+ # SchemaPlus.setup do |config|
146
+ # config.validations.auto_create = ...
147
+ # end
148
+ #
149
+ class Validations < Valuable
150
+ ##
151
+ # :attr_accessor: auto_create
152
+ #
153
+ # Whether to automatically create validations based on database constraints.
154
+ # Boolean, default is +true+.
155
+ has_value :auto_create, :klass => :boolean, :default => true
156
+
157
+ ##
158
+ # :attr_accessor: only
159
+ #
160
+ # List of field names to include in automatic validation.
161
+ # Value is a single name, and array of names, or +nil+. Default is +nil+.
162
+ has_value :only, :default => nil
163
+
164
+ ##
165
+ # :attr_accessor: except
166
+ #
167
+ # List of field names to exclude from automatic validation.
168
+ # Value is a single name, an array of names, or +nil+. Default is <tt>[:created_at, :updated_at, :created_on, :updated_on]</tt>.
169
+ has_value :except, :default => [:created_at, :updated_at, :created_on, :updated_on]
170
+
171
+ ##
172
+ # :attr_accessor: only_type
173
+ #
174
+ # List of validation types to exclude from automatic validation.
175
+ # Value is a single type, and array of types, or +nil+. Default is +nil+.
176
+ # A type is specified as, e.g., +:validates_presence_of+ or simply +:presence+.
177
+ has_value :except_type, :default => nil
178
+
179
+ ##
180
+ # :attr_accessor: only_type
181
+ #
182
+ # List of validation types to include in automatic validation.
183
+ # Value is a single type, and array of types, or +nil+. Default is +nil+.
184
+ # A type is specified as, e.g., +:validates_presence_of+ or simply +:presence+.
185
+ has_value :only_type, :default => nil
186
+
187
+ end
188
+ has_value :validations, :klass => Validations, :default => Validations.new
189
+
190
+
191
+ def dup #:nodoc:
192
+ self.class.new(Hash[attributes.collect{ |key, val| [key, Valuable === val ? val.class.new(val.attributes) : val] }])
193
+ end
194
+
195
+ def update_attributes(opts)#:nodoc:
196
+ opts = opts.dup
197
+ opts.keys.each { |key| self.send(key).update_attributes(opts.delete(key)) if self.class.attributes.include? key and Hash === opts[key] }
198
+ super(opts)
199
+ self
200
+ end
201
+
202
+ def merge(opts)#:nodoc:
203
+ dup.update_attributes(opts)
204
+ end
205
+
206
+ end
207
+
208
+ # Returns the global configuration, i.e., the singleton instance of Config
209
+ def self.config
210
+ @config ||= Config.new
211
+ end
212
+
213
+ # Initialization block is passed a global Config instance that can be
214
+ # used to configure SchemaPlus behavior. E.g., if you want to disable
215
+ # automation creation of foreign key constraints for columns name *_id,
216
+ # put the following in config/initializers/schema_plus.rb :
217
+ #
218
+ # SchemaPlus.setup do |config|
219
+ # config.foreign_keys.auto_create = false
220
+ # end
221
+ #
222
+ def self.setup # :yields: config
223
+ yield config
224
+ end
225
+
226
+ def self.insert_connection_adapters #:nodoc:
227
+ return if @inserted_connection_adapters
228
+ @inserted_connection_adapters = true
229
+ ::ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, SchemaPlus::ActiveRecord::ConnectionAdapters::AbstractAdapter)
230
+ ::ActiveRecord::ConnectionAdapters::Column.send(:include, SchemaPlus::ActiveRecord::ConnectionAdapters::Column)
231
+ ::ActiveRecord::ConnectionAdapters::IndexDefinition.send(:include, SchemaPlus::ActiveRecord::ConnectionAdapters::IndexDefinition)
232
+ # (mysql2 v0.2.7 uses its own IndexDefinition, which is compatible with the monkey patches; so if that constant exists, include the patches
233
+ ::ActiveRecord::ConnectionAdapters::Mysql2IndexDefinition.send(:include, SchemaPlus::ActiveRecord::ConnectionAdapters::IndexDefinition) if defined? ::ActiveRecord::ConnectionAdapters::Mysql2IndexDefinition
234
+ ::ActiveRecord::ConnectionAdapters::SchemaStatements.send(:include, SchemaPlus::ActiveRecord::ConnectionAdapters::SchemaStatements)
235
+ ::ActiveRecord::ConnectionAdapters::TableDefinition.send(:include, SchemaPlus::ActiveRecord::ConnectionAdapters::TableDefinition)
236
+ end
237
+
238
+ def self.insert #:nodoc:
239
+ return if @inserted
240
+ @inserted = true
241
+ insert_connection_adapters
242
+ ::ActiveRecord::Base.send(:include, SchemaPlus::ActiveRecord::Base)
243
+ ::ActiveRecord::Migration.send(:include, SchemaPlus::ActiveRecord::Migration)
244
+ ::ActiveRecord::Schema.send(:include, SchemaPlus::ActiveRecord::Schema)
245
+ ::ActiveRecord::SchemaDumper.send(:include, SchemaPlus::ActiveRecord::SchemaDumper)
246
+ end
247
+
248
+ end