class ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
Константы
- INDEX_TYPES
- INDEX_USINGS
- LOST_CONNECTION_ERROR_MESSAGES
- NATIVE_DATABASE_TYPES
- QUOTED_FALSE
Публичные методы класса
По умолчанию, MysqlAdapter будет рассматривать все столбцы типа tinyint(1) как булевы. Если вы хотите отключить эту эмуляцию (что было стандартным поведением в версиях 0.13.1 и ранее), вы можете добавить следующую строку в свой файл application.rb:
ActiveRecord::ConnectionAdapters::Mysql[2]Adapter.emulate_booleans = false
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 141 class_attribute :emulate_booleans
FIXME: Сделайте первый параметр более похожим для двух адаптеров
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 175
def initialize(connection, logger, connection_options, config)
super(connection, logger)
@connection_options, @config = connection_options, config
@quoted_column_names, @quoted_table_names = {}, {}
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
@prepared_statements = true
@visitor = Arel::Visitors::MySQL.new self
else
@visitor = unprepared_visitor
end
end Публичные методы экземпляра
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 560
def add_column_position!(sql, options)
if options[:first]
sql << " FIRST"
elsif options[:after]
sql << " AFTER #{quote_column_name(options[:after])}"
end
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 318 def begin_db_transaction execute "BEGIN" end
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 322
def begin_isolated_db_transaction(isolation)
execute "SET TRANSACTION ISOLATION LEVEL #{transaction_isolation_levels.fetch(isolation)}"
begin_db_transaction
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 597
def case_insensitive_comparison(table, attribute, column, value)
if column.case_sensitive?
super
else
table[attribute].eq(value)
end
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 593 def case_sensitive_modifier(node) Arel::Nodes::Bin.new(node) end
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 499 def change_column_default(table_name, column_name, default) column = column_for(table_name, column_name) change_column table_name, column_name, column.sql_type, :default => default end
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 504
def change_column_null(table_name, column_name, null, default = nil)
column = column_for(table_name, column_name)
unless null || default.nil?
execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
end
change_column table_name, column_name, column.sql_type, :null => null
end Возвращает кодировку символов базы данных.
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 390 def charset show_variable 'character_set_database' end
Возвращает стратегию сортировки базы данных.
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 395 def collation show_variable 'collation_database' end
Создает новую базу данных MySQL с необязательными :charset и :collation. Кодировка по умолчанию utf8.
Пример:
create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin' create_database 'matt_development' create_database 'matt_development', charset: :big5
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 369
def create_database(name, options = {})
if options[:collation]
execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}` COLLATE `#{options[:collation]}`"
else
execute "CREATE DATABASE `#{name}` DEFAULT CHARACTER SET `#{options[:charset] || 'utf8'}`"
end
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 385 def current_database select_value 'SELECT DATABASE() as db' end
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 487
def drop_table(table_name, options = {})
execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE #{quote_table_name(table_name)}"
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 347 def empty_insert_statement_value "VALUES ()" end
Выполняет SQL-запрос в контексте этого соединения.
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 302
def execute(sql, name = nil)
log(sql, name) { @connection.query(sql) }
end Технически MySQL позволяет создавать индексы с синтаксисом порядка сортировки, но в настоящее время (версия 5.5) они ещё не реализованы.
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 207 def supports_index_sort_order? true end
Возвращает true, так как этот адаптер подключения поддерживает миграции.
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 193 def supports_migrations? true end
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 197 def supports_primary_key? true end
MySQL 4 технически поддерживает изоляцию транзакций, но она подвержена ошибке, при которой уровень транзакции сохраняется для всей сессии:
bugs.mysql.com/bug.php?id=39170
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 226 def supports_transaction_isolation? version[0] >= 5 end
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 409
def table_exists?(name)
return false unless name
return true if tables(nil, nil, name).any?
name = name.to_s
schema, table = name.split('.', 2)
unless table # A table was provided without a schema
table = schema
schema = nil
end
tables(nil, schema, table).any?
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 211
def type_cast(value, column)
case value
when TrueClass
1
when FalseClass
0
else
super
end
end Преобразование логических типов Rails в специфические типы данных MySQL.
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 529
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
case type.to_s
when 'binary'
case limit
when 0..0xfff; "varbinary(#{limit})"
when nil; "blob"
when 0x1000..0xffffffff; "blob(#{limit})"
else raise(ActiveRecordError, "No binary type has character length #{limit}")
end
when 'integer'
case limit
when 1; 'tinyint'
when 2; 'smallint'
when 3; 'mediumint'
when nil, 4, 11; 'int(11)' # compatibility with MySQL default
when 5..8; 'bigint'
else raise(ActiveRecordError, "No integer type has byte size #{limit}")
end
when 'text'
case limit
when 0..0xff; 'tinytext'
when nil, 0x100..0xffff; 'text'
when 0x10000..0xffffff; 'mediumtext'
when 0x1000000..0xffffffff; 'longtext'
else raise(ActiveRecordError, "No text type has character length #{limit}")
end
else
super
end
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 613 def valid_type?(type) !native_database_types[type].nil? end
Защищенные методы экземпляров
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 666
def add_column_sql(table_name, column_name, type, options = {})
td = create_table_definition table_name, options[:temporary], options[:options]
cd = td.new_column_definition(column_name, type, options)
schema_creation.visit_AddColumn cd
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 630
def add_index_length(option_strings, column_names, options = {})
if options.is_a?(Hash) && length = options[:length]
case length
when Hash
column_names.each {|name| option_strings[name] += "(#{length[name]})" if length.has_key?(name) && length[name].present?}
when Fixnum
column_names.each {|name| option_strings[name] += "(#{length})"}
end
end
return option_strings
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 710
def add_index_sql(table_name, column_name, options = {})
index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
"ADD #{index_type} INDEX #{index_name} (#{index_columns})"
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 720
def add_timestamps_sql(table_name, options = {})
[add_column_sql(table_name, :created_at, :datetime, options), add_column_sql(table_name, :updated_at, :datetime, options)]
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 672
def change_column_sql(table_name, column_name, type, options = {})
column = column_for(table_name, column_name)
unless options_include_default?(options)
options[:default] = column.default
end
unless options.has_key?(:null)
options[:null] = column.null
end
options[:name] = column.name
schema_creation.accept ChangeColumnDefinition.new column, type, options
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 643
def quoted_columns_for_index(column_names, options = {})
option_strings = Hash[column_names.map {|name| [name, '']}]
# add index length
option_strings = add_index_length(option_strings, column_names, options)
# add index sort order
option_strings = add_index_sort_order(option_strings, column_names, options)
column_names.map {|name| quote_column_name(name) + option_strings[name]}
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 702
def remove_column_sql(table_name, column_name, type = nil, options = {})
"DROP #{quote_column_name(column_name)}"
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 706
def remove_columns_sql(table_name, *column_names)
column_names.map {|column_name| remove_column_sql(table_name, column_name) }
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 715
def remove_index_sql(table_name, options = {})
index_name = index_name_for_remove(table_name, options)
"DROP INDEX #{index_name}"
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 724 def remove_timestamps_sql(table_name) [remove_column_sql(table_name, :updated_at), remove_column_sql(table_name, :created_at)] end
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 687
def rename_column_sql(table_name, column_name, new_column_name)
options = { name: new_column_name }
if column = columns(table_name).find { |c| c.name == column_name.to_s }
options[:default] = column.default
options[:null] = column.null
options[:auto_increment] = (column.extra == "auto_increment")
else
raise ActiveRecordError, "No such column: #{table_name}.#{column_name}"
end
current_type = select_one("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE '#{column_name}'", 'SCHEMA')["Type"]
schema_creation.accept ChangeColumnDefinition.new column, current_type, options
end MySQL слишком глуп, чтобы создавать временную таблицу для использования подзапроса, поэтому нам нужно подтолкнуть его с помощью подзапроса в подзапросе. Фу!
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 621
def subquery_for(key, select)
subsubselect = select.clone
subsubselect.projections = [key]
subselect = Arel::SelectManager.new(select.engine)
subselect.project Arel.sql(key.name)
subselect.from subsubselect.as('__active_record_temp')
end # File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 655
def translate_exception(exception, message)
case error_number(exception)
when 1062
RecordNotUnique.new(message, exception)
when 1452
InvalidForeignKey.new(message, exception)
else
super
end
end
© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.