Class: ActiveRecord::ConnectionAdapters::Mysql2Adapter

Inherits:
AbstractMysqlAdapter
  • Object
show all
Includes:
ArJdbc::Abstract::ConnectionManagement, ArJdbc::Abstract::DatabaseStatements, ArJdbc::Abstract::StatementCache, ArJdbc::Abstract::TransactionSupport, ArJdbc::MySQL
Defined in:
lib/arjdbc/mysql/adapter.rb

Constant Summary collapse

ADAPTER_NAME =
'Mysql2'
TYPE_MAP =

NOTE: redefines constant defined in abstract class however this time will use methods defined in the mysql abstract class and map properly mysql types.

Type::TypeMap.new.tap { |m| initialize_type_map(m) }

Constants included from ArJdbc::Abstract::DatabaseStatements

ArJdbc::Abstract::DatabaseStatements::NO_BINDS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ArJdbc::Abstract::TransactionSupport

#begin_db_transaction, #begin_isolated_db_transaction, #commit_db_transaction, #create_savepoint, #exec_rollback_db_transaction, #exec_rollback_to_savepoint, #release_savepoint

Methods included from ArJdbc::Abstract::StatementCache

#delete_cached_statement, #fetch_cached_statement

Methods included from ArJdbc::Abstract::DatabaseStatements

#exec_insert, #exec_update, #internal_exec_query, #select_all

Methods included from ArJdbc::Abstract::ConnectionManagement

#really_valid?

Constructor Details

#initializeMysql2Adapter

Returns a new instance of Mysql2Adapter.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/arjdbc/mysql/adapter.rb', line 66

def initialize(...)
  super

  @config[:flags] ||= 0

  # JDBC mysql appears to use found rows by default: https://dev.mysql.com/doc/connector-j/en/connector-j-connp-props-connection.html
  # if @config[:flags].kind_of? Array
  #   @config[:flags].push "FOUND_ROWS"
  # else
  #   @config[:flags] |= ::Mysql2::Client::FOUND_ROWS
  # end

  @connection_parameters ||= @config
end

Class Method Details

.database_exists?(config) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
# File 'lib/arjdbc/mysql/adapter.rb', line 81

def self.database_exists?(config)
  conn = ActiveRecord::Base.mysql2_connection(config)
  conn && conn.really_valid?
rescue ActiveRecord::NoDatabaseError
  false
ensure
  conn.disconnect! if conn
end

.jdbc_connection_classObject



39
40
41
# File 'lib/arjdbc/mysql/adapter.rb', line 39

def jdbc_connection_class
  ::ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
end

.new_client(conn_params, adapter_instance) ⇒ Object



43
44
45
# File 'lib/arjdbc/mysql/adapter.rb', line 43

def new_client(conn_params, adapter_instance)
  jdbc_connection_class.new(conn_params, adapter_instance)
end

Instance Method Details

#active?Boolean

-- CONNECTION MANAGEMENT ==================================== ++

Returns:

  • (Boolean)


203
204
205
# File 'lib/arjdbc/mysql/adapter.rb', line 203

def active?
  !(@raw_connection.nil? || @raw_connection.closed?) && @lock.synchronize { @raw_connection&.ping } || false
end

#build_explain_clause(options = []) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/arjdbc/mysql/adapter.rb', line 139

def build_explain_clause(options = [])
  return "EXPLAIN" if options.empty?

  explain_clause = "EXPLAIN #{options.join(" ").upcase}"
  
  if analyze_without_explain? && explain_clause.include?("ANALYZE")
    explain_clause.sub("EXPLAIN ", "")
  else
    explain_clause
  end
end

#discard!Object

:nodoc:



219
220
221
222
223
224
225
# File 'lib/arjdbc/mysql/adapter.rb', line 219

def discard! # :nodoc:
  @lock.synchronize do
    super
    @raw_connection&.automatic_close = false
    @raw_connection = nil
  end
end

#disconnect!Object

Disconnects from the database if already connected. Otherwise, this method does nothing.



211
212
213
214
215
216
217
# File 'lib/arjdbc/mysql/adapter.rb', line 211

def disconnect!
  @lock.synchronize do
    super
    @raw_connection&.close
    @raw_connection = nil
  end
end

#each_hash(result) ⇒ Object

:nodoc:



151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/arjdbc/mysql/adapter.rb', line 151

def each_hash(result) # :nodoc:
  if block_given?
    # FIXME: This is C in mysql2 gem and I just made simplest Ruby
    result.each do |row|
      new_hash = {}
      row.each { |k, v| new_hash[k.to_sym] = v }
      yield new_hash
    end
  else
    to_enum(:each_hash, result)
  end
end

#error_number(exception) ⇒ Object



164
165
166
# File 'lib/arjdbc/mysql/adapter.rb', line 164

def error_number(exception)
  exception.error_code if exception.is_a?(JDBCError)
end

#explain(arel, binds = [], options = []) ⇒ Object



130
131
132
133
134
135
136
137
# File 'lib/arjdbc/mysql/adapter.rb', line 130

def explain(arel, binds = [], options = [])
  sql     = build_explain_clause(options) + " " + to_sql(arel, binds)
  start   = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  result  = internal_exec_query(sql, "EXPLAIN", binds)
  elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start

  MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
end

#quote(value, comment = nil) ⇒ Object

FIXME: 5.1 crashes without this. I think this is Arel hitting a fallback path in to_sql.rb. So maybe an untested code path in their source. Still means we are doing something wrong to even hit it.



175
176
177
# File 'lib/arjdbc/mysql/adapter.rb', line 175

def quote(value, comment=nil)
  super(value)
end

#quoted_date(value) ⇒ Object

NOTE: quote_string(string) provided by ArJdbc::MySQL (native code), this piece is also native (mysql2) under MRI: @connection.escape(string)



182
183
184
185
186
187
188
# File 'lib/arjdbc/mysql/adapter.rb', line 182

def quoted_date(value)
  if supports_datetime_with_precision?
    super
  else
    super.sub(/\.\d{6}\z/, '')
  end
end

#supports_comments?Boolean

Returns:

  • (Boolean)


94
95
96
# File 'lib/arjdbc/mysql/adapter.rb', line 94

def supports_comments?
  true
end

#supports_comments_in_create?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/arjdbc/mysql/adapter.rb', line 98

def supports_comments_in_create?
  true
end

#supports_json?Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/arjdbc/mysql/adapter.rb', line 90

def supports_json?
  !mariadb? && database_version >= '5.7.8'
end

#supports_lazy_transactions?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/arjdbc/mysql/adapter.rb', line 106

def supports_lazy_transactions?
  true
end

#supports_savepoints?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/arjdbc/mysql/adapter.rb', line 102

def supports_savepoints?
  true
end

#supports_set_server_option?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/arjdbc/mysql/adapter.rb', line 114

def supports_set_server_option?
  false
end

#supports_transaction_isolation?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/arjdbc/mysql/adapter.rb', line 110

def supports_transaction_isolation?
  true
end

#write_query?(sql) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


126
127
128
# File 'lib/arjdbc/mysql/adapter.rb', line 126

def write_query?(sql) # :nodoc:
  !READ_QUERY.match?(sql)
end