# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 517 def primary_key(table) pk_and_sequence = pk_and_sequence_for(table) pk_and_sequence && pk_and_sequence.first end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 118 def initialize(connection, logger, connection_options, config) super(connection, logger) @connection_options, @config = connection_options, config @quoted_column_names, @quoted_table_names = {}, {} configure_connection end
CONNECTION MANAGEMENT ====================================
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 193 def active? return false unless @connection @connection.ping end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 125 def adapter_name ADAPTER_NAME end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 427 def add_column(table_name, column_name, type, options = {}) add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" add_column_options!(add_column_sql, options) add_column_position!(add_column_sql, options) execute(add_column_sql) end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 494 def add_column_position!(sql, options) if options[:first] sql << " FIRST" elsif options[:after] sql << " AFTER #{quote_column_name(options[:after])}" end end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 315 def add_limit_offset!(sql, options) limit, offset = options[:limit], options[:offset] if limit && offset sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}" elsif limit sql << " LIMIT #{sanitize_limit(limit)}" elsif offset sql << " OFFSET #{offset.to_i}" end sql end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 285 def begin_db_transaction execute "BEGIN" rescue Exception # Transactions aren't supported end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 522 def case_sensitive_equality_operator "= BINARY" end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 449 def change_column(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 change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}" add_column_options!(change_column_sql, options) add_column_position!(change_column_sql, options) execute(change_column_sql) end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 434 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 lib/active_record/connection_adapters/mysql2_adapter.rb, line 439 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
Returns the database character set.
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 371 def charset show_variable 'character_set_database' end
Returns the database collation strategy.
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 376 def collation show_variable 'collation_database' end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 409 def columns(table_name, name = nil) sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}" columns = [] result = execute(sql, :skip_logging) result.each(:symbolize_keys => true, :as => :hash) { |field| columns << Mysql2Column.new(field[:Field], field[:Default], field[:Type], field[:Null] == "YES") } columns end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 291 def commit_db_transaction execute "COMMIT" rescue Exception # Transactions aren't supported end
Create a new MySQL database with optional :charset
and
:collation
. Charset defaults to utf8.
Example:
create_database 'charset_test', :charset => 'latin1', :collation => 'latin1_bin' create_database 'matt_development' create_database 'matt_development', :charset => :big5
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 354 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 lib/active_record/connection_adapters/mysql2_adapter.rb, line 303 def create_savepoint execute("SAVEPOINT #{current_savepoint_name}") end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 419 def create_table(table_name, options = {}) super(table_name, options.reverse_merge(:options => "ENGINE=InnoDB")) end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 366 def current_database select_value 'SELECT DATABASE() as db' end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 208 def disconnect! unless @connection.nil? @connection.close @connection = nil end end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 388 def drop_table(table_name, options = {}) super(table_name, options) end
Executes the SQL statement in the context of this connection.
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 257 def execute(sql, name = nil) # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been # made since we established the connection @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone if name == :skip_logging @connection.query(sql) else log(sql, name) { @connection.query(sql) } end rescue ActiveRecord::StatementInvalid => exception if exception.message.split(":").first =~ %rPackets out of order/ raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings." else raise end end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 392 def indexes(table_name, name = nil) indexes = [] current_index = nil result = execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name) result.each(:symbolize_keys => true, :as => :hash) do |row| if current_index != row[:Key_name] next if row[:Key_name] == PRIMARY # skip the primary key current_index = row[:Key_name] indexes << Mysql2IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, [], []) end indexes.last.columns << row[:Column_name] indexes.last.lengths << row[:Sub_part] end indexes end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 274 def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) super id_value || @connection.last_id end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 526 def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key) where_sql end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 141 def native_database_types NATIVE_DATABASE_TYPES end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 507 def pk_and_sequence_for(table) keys = [] result = execute("describe #{quote_table_name(table)}") result.each(:symbolize_keys => true, :as => :hash) do |row| keys << row[:Field] if row[:Key] == "PRI" end keys.length == 1 ? [keys.first, nil] : nil end
Returns just a table's primary key
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 517 def primary_key(table) pk_and_sequence = pk_and_sequence_for(table) pk_and_sequence && pk_and_sequence.first end
QUOTING ==================================================
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 147 def quote(value, column = nil) if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary) s = column.class.string_to_binary(value).unpack("H*")[0] "x'#{s}'" elsif value.kind_of?(BigDecimal) value.to_s("F") else super end end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 166 def quote_string(string) @connection.escape(string) end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 174 def quoted_false QUOTED_FALSE end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 170 def quoted_true QUOTED_TRUE end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 198 def reconnect! disconnect! connect end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 342 def recreate_database(name, options = {}) drop_database(name) create_database(name, options) end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 311 def release_savepoint execute("RELEASE SAVEPOINT #{current_savepoint_name}") end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 466 def rename_column(table_name, column_name, new_column_name) options = {} if column = columns(table_name).find { |c| c.name == column_name.to_s } options[:default] = column.default options[:null] = column.null 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}'")["Type"] rename_column_sql = "ALTER TABLE #{quote_table_name(table_name)} CHANGE #{quote_column_name(column_name)} #{quote_column_name(new_column_name)} #{current_type}" add_column_options!(rename_column_sql, options) execute(rename_column_sql) end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 423 def rename_table(table_name, new_name) execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}" end
this is set to true in 2.3, but we don't want it to be
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 204 def requires_reloading? false end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 215 def reset! disconnect! connect end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 297 def rollback_db_transaction execute "ROLLBACK" rescue Exception # Transactions aren't supported end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 307 def rollback_to_savepoint execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}") end
Returns an array of arrays containing the field values. Order is the same
as that returned by columns
.
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 252 def select_rows(sql, name = nil) execute(sql, name).to_a end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 502 def show_variable(name) variables = select_all("SHOW VARIABLES LIKE '#{name}'") variables.first['Value'] unless variables.empty? end
SCHEMA STATEMENTS ========================================
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 329 def structure_dump if supports_views? sql = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'" else sql = "SHOW TABLES" end select_all(sql).inject("") do |structure, table| table.delete('Table_type') structure += select_one("SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}")["Create Table"] + ";\n\n" end end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 129 def supports_migrations? true end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 133 def supports_primary_key? true end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 137 def supports_savepoints? true end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 380 def tables(name = nil) tables = [] execute("SHOW TABLES", name).each do |field| tables << field.first end tables end
Maps logical Rails types to MySQL-specific data types.
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 481 def type_to_sql(type, limit = nil, precision = nil, scale = nil) return super unless type.to_s == '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 end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 280 def update_sql(sql, name = nil) super @connection.affected_rows end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 531 def quoted_columns_for_index(column_names, options = {}) length = options[:length] if options.is_a?(Hash) quoted_column_names = case length when Hash column_names.map {|name| length[name] ? "#{quote_column_name(name)}(#{length[name]})" : quote_column_name(name) } when Fixnum column_names.map {|name| "#{quote_column_name(name)}(#{length})"} else column_names.map {|name| quote_column_name(name) } end end
# File lib/active_record/connection_adapters/mysql2_adapter.rb, line 544 def translate_exception(exception, message) return super unless exception.respond_to?(:error_number) case exception.error_number when 1062 RecordNotUnique.new(message, exception) when 1452 InvalidForeignKey.new(message, exception) else super end end