aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb125
1 files changed, 84 insertions, 41 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index e3115abe66..d3fbc18f97 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -23,6 +23,25 @@ module ActiveRecord
table_name[0...table_alias_length].tr('.', '_')
end
+ # Returns the relation names useable to back Active Record models.
+ # For most adapters this means all #tables and #views.
+ def data_sources
+ tables | views
+ end
+
+ # Checks to see if the data source +name+ exists on the database.
+ #
+ # data_source_exists?(:ebooks)
+ #
+ def data_source_exists?(name)
+ data_sources.include?(name.to_s)
+ end
+
+ # Returns an array of table names defined in the database.
+ def tables(name = nil)
+ raise NotImplementedError, "#tables is not implemented"
+ end
+
# Checks to see if the table +table_name+ exists on the database.
#
# table_exists?(:developers)
@@ -31,6 +50,19 @@ module ActiveRecord
tables.include?(table_name.to_s)
end
+ # Returns an array of view names defined in the database.
+ def views
+ raise NotImplementedError, "#views is not implemented"
+ end
+
+ # Checks to see if the view +view_name+ exists on the database.
+ #
+ # view_exists?(:ebooks)
+ #
+ def view_exists?(view_name)
+ views.include?(view_name.to_s)
+ end
+
# Returns an array of indexes for the given table.
# def indexes(table_name, name = nil) end
@@ -88,10 +120,16 @@ module ActiveRecord
(!options.key?(:null) || c.null == options[:null]) }
end
+ # Returns just a table's primary key
+ def primary_key(table_name)
+ pks = primary_keys(table_name)
+ pks.first if pks.one?
+ end
+
# Creates a new table with the name +table_name+. +table_name+ may either
# be a String or a Symbol.
#
- # There are two ways to work with +create_table+. You can use the block
+ # There are two ways to work with #create_table. You can use the block
# form or the regular form, like this:
#
# === Block form
@@ -123,7 +161,7 @@ module ActiveRecord
# The +options+ hash can include the following keys:
# [<tt>:id</tt>]
# Whether to automatically add a primary key column. Defaults to true.
- # Join tables for +has_and_belongs_to_many+ should set it to false.
+ # Join tables for {ActiveRecord::Base.has_and_belongs_to_many}[rdoc-ref:Associations::ClassMethods#has_and_belongs_to_many] should set it to false.
#
# A Symbol can be used to specify the type of the generated primary key column.
# [<tt>:primary_key</tt>]
@@ -131,7 +169,8 @@ module ActiveRecord
# Defaults to +id+. If <tt>:id</tt> is false this option is ignored.
#
# Note that Active Record models will automatically detect their
- # primary key. This can be avoided by using +self.primary_key=+ on the model
+ # primary key. This can be avoided by using
+ # {self.primary_key=}[rdoc-ref:AttributeMethods::PrimaryKey::ClassMethods#primary_key=] on the model
# to define the key explicitly.
#
# [<tt>:options</tt>]
@@ -153,7 +192,7 @@ module ActiveRecord
# generates:
#
# CREATE TABLE suppliers (
- # id int(11) DEFAULT NULL auto_increment PRIMARY KEY
+ # id int auto_increment PRIMARY KEY
# ) ENGINE=InnoDB DEFAULT CHARSET=utf8
#
# ====== Rename the primary key column
@@ -165,7 +204,7 @@ module ActiveRecord
# generates:
#
# CREATE TABLE objects (
- # guid int(11) DEFAULT NULL auto_increment PRIMARY KEY,
+ # guid int auto_increment PRIMARY KEY,
# name varchar(80)
# )
#
@@ -215,7 +254,11 @@ module ActiveRecord
Base.get_primary_key table_name.to_s.singularize
end
- td.primary_key pk, options.fetch(:id, :primary_key), options
+ if pk.is_a?(Array)
+ td.primary_keys pk
+ else
+ td.primary_key pk, options.fetch(:id, :primary_key), options
+ end
end
yield td if block_given?
@@ -232,10 +275,6 @@ module ActiveRecord
end
end
- td.foreign_keys.each_pair do |other_table_name, foreign_key_options|
- add_foreign_key(table_name, other_table_name, foreign_key_options)
- end
-
result
end
@@ -258,7 +297,7 @@ module ActiveRecord
# Set to true to drop the table before creating it.
# Defaults to false.
#
- # Note that +create_join_table+ does not create any indices by default; you can use
+ # Note that #create_join_table does not create any indices by default; you can use
# its block form to do so yourself:
#
# create_join_table :products, :categories do |t|
@@ -293,11 +332,11 @@ module ActiveRecord
end
# Drops the join table specified by the given arguments.
- # See +create_join_table+ for details.
+ # See #create_join_table for details.
#
# Although this command ignores the block if one is given, it can be helpful
# to provide one in a migration's +change+ method so it can be reverted.
- # In that case, the block will be used by create_join_table.
+ # In that case, the block will be used by #create_join_table.
def drop_join_table(table_1, table_2, options = {})
join_table_name = find_join_table_name(table_1, table_2, options)
drop_table(join_table_name)
@@ -315,7 +354,7 @@ module ActiveRecord
# [<tt>:bulk</tt>]
# Set this to true to make this a bulk alter query, such as
#
- # ALTER TABLE `users` ADD COLUMN age INT(11), ADD COLUMN birthdate DATETIME ...
+ # ALTER TABLE `users` ADD COLUMN age INT, ADD COLUMN birthdate DATETIME ...
#
# Defaults to false.
#
@@ -402,7 +441,7 @@ module ActiveRecord
#
# Although this command ignores most +options+ and the block if one is given,
# it can be helpful to provide these in a migration's +change+ method so it can be reverted.
- # In that case, +options+ and the block will be used by create_table.
+ # In that case, +options+ and the block will be used by #create_table.
def drop_table(table_name, options = {})
execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
end
@@ -469,7 +508,7 @@ module ActiveRecord
raise NotImplementedError, "change_column_default is not implemented"
end
- # Sets or removes a +NOT NULL+ constraint on a column. The +null+ flag
+ # Sets or removes a <tt>NOT NULL</tt> constraint on a column. The +null+ flag
# indicates whether the value can be +NULL+. For example
#
# change_column_null(:users, :nickname, false)
@@ -481,7 +520,7 @@ module ActiveRecord
# allows them to be +NULL+ (drops the constraint).
#
# The method accepts an optional fourth argument to replace existing
- # +NULL+s with some other value. Use that one when enabling the
+ # <tt>NULL</tt>s with some other value. Use that one when enabling the
# constraint if needed, since otherwise those rows would not be valid.
#
# Please note the fourth argument does not set a column's default.
@@ -535,6 +574,8 @@ module ActiveRecord
#
# CREATE INDEX by_name ON accounts(name(10))
#
+ # ====== Creating an index with specific key lengths for multiple keys
+ #
# add_index(:accounts, [:name, :surname], name: 'by_name_surname', length: {name: 10, surname: 15})
#
# generates:
@@ -607,10 +648,7 @@ module ActiveRecord
# remove_index :accounts, name: :by_branch_party
#
def remove_index(table_name, options = {})
- remove_index!(table_name, index_name_for_remove(table_name, options))
- end
-
- def remove_index!(table_name, index_name) #:nodoc:
+ index_name = index_name_for_remove(table_name, options)
execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
end
@@ -657,7 +695,7 @@ module ActiveRecord
# Adds a reference. The reference column is an integer by default,
# the <tt>:type</tt> option can be used to specify a different type.
# Optionally adds a +_type+ column, if <tt>:polymorphic</tt> option is provided.
- # <tt>add_reference</tt> and <tt>add_belongs_to</tt> are acceptable.
+ # #add_reference and #add_belongs_to are acceptable.
#
# The +options+ hash can include the following keys:
# [<tt>:type</tt>]
@@ -665,9 +703,11 @@ module ActiveRecord
# [<tt>:index</tt>]
# Add an appropriate index. Defaults to false.
# [<tt>:foreign_key</tt>]
- # Add an appropriate foreign key. Defaults to false.
+ # Add an appropriate foreign key constraint. Defaults to false.
# [<tt>:polymorphic</tt>]
# Whether an additional +_type+ column should be added. Defaults to false.
+ # [<tt>:null</tt>]
+ # Whether the column allows nulls. Defaults to true.
#
# ====== Create a user_id integer column
#
@@ -685,13 +725,17 @@ module ActiveRecord
#
# add_reference(:products, :supplier, foreign_key: true)
#
+ # ====== Create a supplier_id column and a foreign key to the firms table
+ #
+ # add_reference(:products, :supplier, foreign_key: {to_table: :firms})
+ #
def add_reference(table_name, *args)
ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self))
end
alias :add_belongs_to :add_reference
# Removes the reference(s). Also removes a +type+ column if one exists.
- # <tt>remove_reference</tt> and <tt>remove_belongs_to</tt> are acceptable.
+ # #remove_reference and #remove_belongs_to are acceptable.
#
# ====== Remove the reference
#
@@ -717,7 +761,7 @@ module ActiveRecord
alias :remove_belongs_to :remove_reference
# Returns an array of foreign keys for the given table.
- # The foreign keys are represented as +ForeignKeyDefinition+ objects.
+ # The foreign keys are represented as ForeignKeyDefinition objects.
def foreign_keys(table_name)
raise NotImplementedError, "foreign_keys is not implemented"
end
@@ -761,21 +805,13 @@ module ActiveRecord
# [<tt>:name</tt>]
# The constraint name. Defaults to <tt>fk_rails_<identifier></tt>.
# [<tt>:on_delete</tt>]
- # Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade:+ and +:restrict+
+ # Action that happens <tt>ON DELETE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
# [<tt>:on_update</tt>]
- # Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade:+ and +:restrict+
+ # Action that happens <tt>ON UPDATE</tt>. Valid values are +:nullify+, +:cascade+ and +:restrict+
def add_foreign_key(from_table, to_table, options = {})
return unless supports_foreign_keys?
- options[:column] ||= foreign_key_column_for(to_table)
-
- options = {
- column: options[:column],
- primary_key: options[:primary_key],
- name: foreign_key_name(from_table, options),
- on_delete: options[:on_delete],
- on_update: options[:on_update]
- }
+ options = foreign_key_options(from_table, to_table, options)
at = create_alter_table from_table
at.add_foreign_key to_table, options
@@ -843,6 +879,13 @@ module ActiveRecord
"#{name.singularize}_id"
end
+ def foreign_key_options(from_table, to_table, options) # :nodoc:
+ options = options.dup
+ options[:column] ||= foreign_key_column_for(to_table)
+ options[:name] ||= foreign_key_name(from_table, options)
+ options
+ end
+
def dump_schema_information #:nodoc:
sm_table = ActiveRecord::Migrator.schema_migrations_table_name
@@ -857,7 +900,7 @@ module ActiveRecord
ActiveRecord::SchemaMigration.create_table
end
- def assume_migrated_upto_version(version, migrations_paths = ActiveRecord::Migrator.migrations_paths)
+ def assume_migrated_upto_version(version, migrations_paths)
migrations_paths = Array(migrations_paths)
version = version.to_i
sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
@@ -984,6 +1027,10 @@ module ActiveRecord
[index_name, index_type, index_columns, index_options, algorithm, using]
end
+ def options_include_default?(options)
+ options.include?(:default) && !(options[:null] == false && options[:default].nil?)
+ end
+
protected
def add_index_sort_order(option_strings, column_names, options = {})
if options.is_a?(Hash) && order = options[:order]
@@ -1010,10 +1057,6 @@ module ActiveRecord
column_names.map {|name| quote_column_name(name) + option_strings[name]}
end
- def options_include_default?(options)
- options.include?(:default) && !(options[:null] == false && options[:default].nil?)
- end
-
def index_name_for_remove(table_name, options = {})
index_name = index_name(table_name, options)