Module: SchemaPlus::ActiveRecord::ConnectionAdapters::AbstractAdapter
- Defined in:
- lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb
Overview
SchemaPlus adds several methods to ActiveRecord::ConnectionAdapters::AbstractAdapter. In most cases you don’t call these directly, but rather the methods that define things are called by schema statements, and methods that query things are called by ActiveRecord::Base.
Defined Under Namespace
Modules: AddColumnOptions, VisitTableDefinition
Class Method Summary collapse
Instance Method Summary collapse
-
#_build_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {}) ⇒ Object
:nodoc:.
-
#add_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {}) ⇒ Object
Define a foreign key constraint.
-
#add_foreign_key_sql(table_name, column_names, references_table_name, references_column_names, options = {}) ⇒ Object
called directly by AT’s bulk_change_table, for migration change_table :name, :bulk => true { … }.
-
#create_view(view_name, definition, options = {}) ⇒ Object
Create a view given the SQL definition.
-
#drop_table(name, options = {}) ⇒ Object
Extends rails’ drop_table to include these options: :cascade :if_exists.
-
#drop_view(view_name, options = {}) ⇒ Object
Drop the named view.
-
#foreign_keys(table_name, name = nil) ⇒ Object
(abstract) Return the ForeignKeyDefinition objects for foreign key constraints defined on this table.
-
#initialize_with_schema_plus(*args) ⇒ Object
:nodoc:.
-
#remove_foreign_key(table_name, *args) ⇒ Object
Remove a foreign key constraint.
- #remove_foreign_key_sql(table_name, *args) ⇒ Object
-
#remove_index_with_schema_plus(table_name, *args) ⇒ Object
Extends rails’ remove_index to include this options: :if_exists.
-
#rename_indexes_and_foreign_keys(oldname, newname) ⇒ Object
called from individual adpaters, after renaming table from old name to.
-
#reverse_foreign_keys(table_name, name = nil) ⇒ Object
(abstract) Return the ForeignKeyDefinition objects for foreign key constraints defined on other tables that reference this table.
-
#supports_partial_indexes? ⇒ Boolean
Returns true if the database supports parital indexes (abstract; only Postgresql returns true).
-
#view_definition(view_name, name = nil) ⇒ Object
(abstract) Returns the SQL definition of a given view.
-
#views(name = nil) ⇒ Object
(abstract) Returns the names of all views, as an array of strings.
Class Method Details
.included(base) ⇒ Object
:nodoc:
14 15 16 17 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 14 def self.included(base) #:nodoc: base.alias_method_chain :initialize, :schema_plus base.alias_method_chain :remove_index, :schema_plus end |
.proper_table_name(name) ⇒ Object
94 95 96 97 98 99 100 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 94 def self.proper_table_name(name) if ::ActiveRecord::Migration.instance_methods(false).include? :proper_table_name proper_name = ::ActiveRecord::Migration.new.proper_table_name(name) # Rails >= 4.1 else proper_name = ::ActiveRecord::Migrator.proper_table_name(name) # Rails <= 4.0 ; Deprecated in 4.1 end end |
Instance Method Details
#_build_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {}) ⇒ Object
:nodoc:
88 89 90 91 92 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 88 def _build_foreign_key(table_name, column_names, references_table_name, references_column_names, = {}) #:nodoc: .merge!(:column_names => column_names, :references_column_names => references_column_names) .reverse_merge!(:name => ForeignKeyDefinition.default_name(table_name, column_names)) ForeignKeyDefinition.new(table_name, AbstractAdapter.proper_table_name(references_table_name), ) end |
#add_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {}) ⇒ Object
Define a foreign key constraint. Valid options are :on_update, :on_delete, and :deferrable, with values as described at ConnectionAdapters::ForeignKeyDefinition
(NOTE: Sqlite3 does not support altering a table to add foreign-key constraints; they must be included in the table specification when it’s created. If you’re using Sqlite3, this method will raise an error.)
76 77 78 79 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 76 def add_foreign_key(table_name, column_names, references_table_name, references_column_names, = {}) foreign_key_sql = add_foreign_key_sql(table_name, column_names, references_table_name, references_column_names, ) execute "ALTER TABLE #{quote_table_name(table_name)} #{foreign_key_sql}" end |
#add_foreign_key_sql(table_name, column_names, references_table_name, references_column_names, options = {}) ⇒ Object
called directly by AT’s bulk_change_table, for migration change_table :name, :bulk => true { … }
83 84 85 86 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 83 def add_foreign_key_sql(table_name, column_names, references_table_name, references_column_names, = {}) #:nodoc: foreign_key = _build_foreign_key(table_name, column_names, references_table_name, references_column_names, ) "ADD #{foreign_key.to_sql}" end |
#create_view(view_name, definition, options = {}) ⇒ Object
Create a view given the SQL definition. Specify :force => true to first drop the view if it already exists.
50 51 52 53 54 55 56 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 50 def create_view(view_name, definition, ={}) definition = definition.to_sql if definition.respond_to? :to_sql if [:force] drop_view(view_name, if_exists: true) end execute "CREATE VIEW #{quote_table_name(view_name)} AS #{definition}" end |
#drop_table(name, options = {}) ⇒ Object
Extends rails’ drop_table to include these options:
:cascade
:if_exists
143 144 145 146 147 148 149 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 143 def drop_table(name, = {}) sql = "DROP TABLE" sql += " IF EXISTS" if [:if_exists] sql += " #{quote_table_name(name)}" sql += " CASCADE" if [:cascade] execute sql end |
#drop_view(view_name, options = {}) ⇒ Object
Drop the named view. Specify :if_exists => true to fail silently if the view doesn’t exist.
60 61 62 63 64 65 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 60 def drop_view(view_name, = {}) sql = "DROP VIEW" sql += " IF EXISTS" if [:if_exists] sql += " #{quote_table_name(view_name)}" execute sql end |
#foreign_keys(table_name, name = nil) ⇒ Object
(abstract) Return the ForeignKeyDefinition objects for foreign key constraints defined on this table
279 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 279 def foreign_keys(table_name, name = nil) raise "Internal Error: Connection adapter didn't override abstract function"; [] end |
#initialize_with_schema_plus(*args) ⇒ Object
:nodoc:
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 19 def initialize_with_schema_plus(*args) #:nodoc: initialize_without_schema_plus(*args) adapter = case adapter_name # name of MySQL adapter depends on mysql gem # * with mysql gem adapter is named MySQL # * with mysql2 gem adapter is named Mysql2 # Here we handle this and hopefully futher adapter names when /^MySQL/i then 'MysqlAdapter' when 'PostgreSQL', 'PostGIS' then 'PostgresqlAdapter' when 'SQLite' then 'Sqlite3Adapter' end if adapter.nil? unless adapter_name == 'JDBC' # ARJDBC ::ActiveRecord::Base.logger.warn "SchemaPlus: Unsupported adapter name #{adapter_name.inspect}. Leaving it alone." end return end adapter_module = SchemaPlus::ActiveRecord::ConnectionAdapters.const_get(adapter) self.class.send(:include, adapter_module) unless self.class.include?(adapter_module) if "#{::ActiveRecord::VERSION::MAJOR}.#{::ActiveRecord::VERSION::MINOR}".to_r >= "4.1".to_r self.class.const_get(:SchemaCreation).send(:include, adapter_module.const_get(:AddColumnOptions)) else self.class.send(:include, adapter_module.const_get(:AddColumnOptions)) end extend(SchemaPlus::ActiveRecord::ForeignKeys) end |
#remove_foreign_key(table_name, *args) ⇒ Object
Remove a foreign key constraint
Arguments are the same as for add_foreign_key, or by name:
remove_foreign_key table_name, column_names, references_table_name, references_column_names
remove_foreign_key name: constraint_name
(NOTE: Sqlite3 does not support altering a table to remove foreign-key constraints. If you’re using Sqlite3, this method will raise an error.)
112 113 114 115 116 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 112 def remove_foreign_key(table_name, *args) case sql = remove_foreign_key_sql(table_name, *args) when String then execute "ALTER TABLE #{quote_table_name(table_name)} #{sql}" end end |
#remove_foreign_key_sql(table_name, *args) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 118 def remove_foreign_key_sql(table_name, *args) column_names, references_table_name, references_column_names, = args ||= {} foreign_key_name = case when args.length == 1 case args[0] when Hash then args[0][:name] else args[0] end else test_fk = _build_foreign_key(table_name, column_names, references_table_name, references_column_names, ) if foreign_keys(table_name).detect { |fk| fk == test_fk } test_fk.name else raise "SchemaPlus: no foreign key constraint found on #{table_name.inspect} matching #{args.inspect}" unless [:if_exists] nil end end 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 end |
#remove_index_with_schema_plus(table_name, *args) ⇒ Object
Extends rails’ remove_index to include this options:
:if_exists
153 154 155 156 157 158 159 160 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 153 def remove_index_with_schema_plus(table_name, *args) = args. if_exists = .delete(:if_exists) .delete(:column) if [:name] and ::ActiveRecord::VERSION::MAJOR < 4 args << if .any? return if if_exists and not index_name_exists?(table_name, [:name] || index_name(table_name, *args), false) remove_index_without_schema_plus(table_name, *args) end |
#rename_indexes_and_foreign_keys(oldname, newname) ⇒ Object
called from individual adpaters, after renaming table from old name to
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 164 def rename_indexes_and_foreign_keys(oldname, newname) #:nodoc: indexes(newname).select{|index| index.name == index_name(oldname, index.columns)}.each do |index| rename_index(newname, index.name, index_name(newname, index.columns)) end foreign_keys(newname).each do |fk| index = indexes(newname).find{|index| index.name == ForeignKeyDefinition.auto_index_name(oldname, fk.column_names)} begin remove_foreign_key(newname, fk.name) rescue NotImplementedError # sqlite3 can't remove foreign keys, so just skip it end # rename the index only when the fk constraint doesn't exist. # mysql doesn't allow the rename (which is a delete & add) # if the index is on a foreign key constraint rename_index(newname, index.name, ForeignKeyDefinition.auto_index_name(newname, index.columns)) if index begin add_foreign_key(newname, fk.column_names, fk.references_table_name, fk.references_column_names, :name => fk.name.sub(/#{oldname}/, newname), :on_update => fk.on_update, :on_delete => fk.on_delete, :deferrable => fk.deferrable) rescue NotImplementedError # sqlite3 can't add foreign keys, so just skip it end end end |
#reverse_foreign_keys(table_name, name = nil) ⇒ Object
(abstract) Return the ForeignKeyDefinition objects for foreign key constraints defined on other tables that reference this table
283 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 283 def reverse_foreign_keys(table_name, name = nil) raise "Internal Error: Connection adapter didn't override abstract function"; [] end |
#supports_partial_indexes? ⇒ Boolean
Returns true if the database supports parital indexes (abstract; only Postgresql returns true)
189 190 191 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 189 def supports_partial_indexes? false end |
#view_definition(view_name, name = nil) ⇒ Object
(abstract) Returns the SQL definition of a given view. This is the literal SQL would come after ‘CREATVE VIEW viewname AS ’ in the SQL statement to create a view.
275 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 275 def view_definition(view_name, name = nil) raise "Internal Error: Connection adapter didn't override abstract function"; end |
#views(name = nil) ⇒ Object
(abstract) Returns the names of all views, as an array of strings
270 |
# File 'lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb', line 270 def views(name = nil) raise "Internal Error: Connection adapter didn't override abstract function"; [] end |