class NewRelic::Agent::Database::Statement
Constants
- DEFAULT_QUERY_NAME
- MYSQL2_PREFIX
- MYSQL_PREFIX
- NEWLINE
- POSTGIS_PREFIX
- POSTGRES_PREFIX
- SQLITE_PREFIX
Attributes
binds[RW]
config[RW]
database_name[RW]
explainer[RW]
host[RW]
name[RW]
port_path_or_id[RW]
sql[RW]
Public Class Methods
new(sql, config = {}, explainer = nil, binds = nil, name = DEFAULT_QUERY_NAME, host = nil, port_path_or_id = nil, database_name = nil)
click to toggle source
# File lib/new_relic/agent/database.rb, line 179 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
adapter()
click to toggle source
This takes a connection config hash from ActiveRecord or Sequel
and returns a symbol describing the associated database adapter
# File lib/new_relic/agent/database.rb, line 204 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
append_sql(new_sql)
click to toggle source
# File lib/new_relic/agent/database.rb, line 231 def append_sql(new_sql) return if new_sql.empty? @sql = Database.truncate_query(@sql << NEWLINE << new_sql) end
explain()
click to toggle source
# File lib/new_relic/agent/database.rb, line 215 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
safe_sql()
click to toggle source
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.
# File lib/new_relic/agent/database.rb, line 193 def safe_sql @safe_sql ||= case Database.record_sql_method when :obfuscated Database.obfuscate_sql(self) when :raw sql.to_s end end
Private Instance Methods
explainable?()
click to toggle source
# File lib/new_relic/agent/database.rb, line 261 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
symbolized_adapter(adapter)
click to toggle source
# File lib/new_relic/agent/database.rb, line 245 def symbolized_adapter(adapter) if adapter.start_with?(POSTGRES_PREFIX) || adapter == POSTGIS_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 else adapter.to_sym end end