class NewRelic::Agent::Database::Statement
Constants
- DEFAULT_QUERY_NAME
- MYSQL2_PREFIX
- MYSQL_PREFIX
- NEWLINE
- POSTGIS_PREFIX
- POSTGRES_PREFIX
- REDSHIFT_PREFIX
- SQLITE_PREFIX
- TRILOGY_PREFIX
Attributes
Public Class Methods
Source
# File lib/new_relic/agent/database.rb, line 215 def initialize(sql, config = {}, explainer = nil, binds = nil, name = DEFAULT_QUERY_NAME, host = nil, port_path_or_id = nil, database_name = nil) @sql = Database.capture_query(sql) @config = config @explainer = explainer @binds = binds @name = name @host = host @port_path_or_id = port_path_or_id @database_name = database_name @safe_sql = nil end
Public Instance Methods
Source
# File lib/new_relic/agent/database.rb, line 240 def adapter return unless @config @adapter ||= if @config[:adapter] symbolized_adapter(@config[:adapter].to_s.downcase) elsif @config[:uri] && @config[:uri].to_s =~ /^jdbc:([^:]+):/ # This case is for Sequel with the jdbc-mysql, jdbc-postgres, or jdbc-sqlite3 gems. symbolized_adapter($1) end end
This takes a connection config hash from ActiveRecord or Sequel
and returns a symbol describing the associated database adapter
Source
# File lib/new_relic/agent/database.rb, line 267 def append_sql(new_sql) return if new_sql.empty? @sql = Database.truncate_query(@sql << NEWLINE << new_sql) end
Source
# File lib/new_relic/agent/database.rb, line 251 def explain return unless explainable? handle_exception_in_explain do start = Process.clock_gettime(Process::CLOCK_MONOTONIC) plan = @explainer.call(self) ::NewRelic::Agent.record_metric( 'Supportability/Database/execute_explain_plan', Process.clock_gettime(Process::CLOCK_MONOTONIC) - start ) return process_resultset(plan, adapter) if plan end end
Source
# File lib/new_relic/agent/database.rb, line 229 def safe_sql @safe_sql ||= case Database.record_sql_method when :obfuscated Database.obfuscate_sql(self) when :raw sql.to_s end end
Returns an sql statement that will be in the form most permissable by the config. The format will be safe for transmission to New Relic.
Private Instance Methods
Source
# File lib/new_relic/agent/database.rb, line 301 def explainable? return false unless @explainer && is_select?(@sql) if @sql.end_with?(ELLIPSIS) NewRelic::Agent.logger.debug('Unable to collect explain plan for truncated query.') return false end if parameterized?(@sql) && (!@binds || @binds.empty?) NewRelic::Agent.logger.debug('Unable to collect explain plan for parameter-less parameterized query.') return false end if !SUPPORTED_ADAPTERS_FOR_EXPLAIN.include?(adapter) NewRelic::Agent.logger.debug("Not collecting explain plan because an unknown connection adapter ('#{adapter}') was used.") return false end if multiple_queries?(@sql) NewRelic::Agent.logger.debug('Unable to collect explain plan for multiple queries.') return false end true end
Source
# File lib/new_relic/agent/database.rb, line 283 def symbolized_adapter(adapter) if adapter.start_with?(POSTGRES_PREFIX) || adapter == POSTGIS_PREFIX || adapter == REDSHIFT_PREFIX :postgres elsif adapter == MYSQL_PREFIX :mysql # For the purpose of fetching explain plans, we need to maintain the distinction # between usage of mysql and mysql2. Obfuscation is the same, though. elsif adapter == MYSQL2_PREFIX :mysql2 elsif adapter.start_with?(SQLITE_PREFIX) :sqlite elsif adapter == TRILOGY_PREFIX :trilogy else adapter.to_sym end end