123456789_123456789_123456789_123456789_123456789_

Module: ActiveRecord::ConnectionAdapters::Mysql2::DatabaseStatements

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Included In:
Defined in: activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#multi_statements_enabled?Boolean (readonly, private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 72

def multi_statements_enabled?
  flags = @config[:flags]

  if flags.is_a?(Array)
    flags.include?("MULTI_STATEMENTS")
  else
    flags.anybits?(::Mysql2::Client::MULTI_STATEMENTS)
  end
end

Instance Method Details

#exec_delete(sql, name = nil, binds = []) Also known as: #exec_update

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 41

def exec_delete(sql, name = nil, binds = []) # :nodoc:
  if without_prepared_statement?(binds)
    with_raw_connection do |conn|
      @affected_rows_before_warnings = nil
      execute_and_free(sql, name) { @affected_rows_before_warnings || conn.affected_rows }
    end
  else
    exec_stmt_and_free(sql, name, binds) { |stmt| stmt.affected_rows }
  end
end

#exec_stmt_and_free(sql, name, binds, cache_stmt: false, async: false) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 108

def exec_stmt_and_free(sql, name, binds, cache_stmt: false, async: false)
  sql = transform_query(sql)
  check_if_write_query(sql)

  mark_transaction_written_if_write(sql)

  type_casted_binds = type_casted_binds(binds)

  log(sql, name, binds, type_casted_binds, async: async) do
    with_raw_connection do |conn|
      sync_timezone_changes(conn)

      if cache_stmt
        stmt = @statements[sql] ||= conn.prepare(sql)
      else
        stmt = conn.prepare(sql)
      end

      begin
        result = ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
          stmt.execute(*type_casted_binds)
        end
        verified!
        result
      rescue ::Mysql2::Error => e
        if cache_stmt
          @statements.delete(sql)
        else
          stmt.close
        end
        raise e
      end

      ret = yield stmt, result
      result.free if result
      stmt.close unless cache_stmt
      ret
    end
  end
end

#exec_update(sql, name = nil, binds = [])

Alias for #exec_delete.

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 51

alias :exec_update :exec_delete

#execute_batch(statements, name = nil) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 58

def execute_batch(statements, name = nil)
  statements = statements.map { |sql| transform_query(sql) }
  combine_multi_statements(statements).each do |statement|
    with_raw_connection do |conn|
      raw_execute(statement, name)
      conn.abandon_results!
    end
  end
end

#internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 21

def internal_exec_query(sql, name = "SQL", binds = [], prepare: false, async: false) # :nodoc:
  if without_prepared_statement?(binds)
    execute_and_free(sql, name, async: async) do |result|
      if result
        build_result(columns: result.fields, rows: result.to_a)
      else
        build_result(columns: [], rows: [])
      end
    end
  else
    exec_stmt_and_free(sql, name, binds, cache_stmt: prepare, async: async) do |_, result|
      if result
        build_result(columns: result.fields, rows: result.to_a)
      else
        build_result(columns: [], rows: [])
      end
    end
  end
end

#last_inserted_id(result) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 68

def last_inserted_id(result)
  @raw_connection&.last_id
end

#raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 96

def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
  log(sql, name, async: async) do
    with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
      sync_timezone_changes(conn)
      result = conn.query(sql)
      verified!
      handle_warnings(sql)
      result
    end
  end
end

#select_all

This method is for internal use only.

Returns an ::ActiveRecord::Result instance.

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 8

def select_all(*, **) # :nodoc:
  result = nil
  with_raw_connection do |conn|
    result = if ExplainRegistry.collect? && prepared_statements
      unprepared_statement { super }
    else
      super
    end
    conn.abandon_results!
  end
  result
end

#sync_timezone_changes(raw_connection) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 54

def sync_timezone_changes(raw_connection)
  raw_connection.query_options[:database_timezone] = default_timezone
end

#with_multi_statements (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/connection_adapters/mysql2/database_statements.rb', line 82

def with_multi_statements
  if multi_statements_enabled?
    return yield
  end

  with_raw_connection do |conn|
    conn.set_server_option(::Mysql2::Client::OPTION_MULTI_STATEMENTS_ON)

    yield
  ensure
    conn.set_server_option(::Mysql2::Client::OPTION_MULTI_STATEMENTS_OFF)
  end
end