Sha256: 3ebeba7fdc95f0b60bf62cca0574cc135eed35e4c6192dbb319c64137cabdbc3

Contents?: true

Size: 1.68 KB

Versions: 1

Compression:

Stored size: 1.68 KB

Contents

require "sql_lexer"
require "json"

module Skylight
  module Normalizers
    class SQL < Normalizer
      register "sql.active_record"

      CAT = "db.sql.query".freeze

      def normalize(trace, name, payload)
        case payload[:name]
        when "SCHEMA", "CACHE"
          return :skip
        else
          name  = CAT
          title = payload[:name] || "SQL"
        end

        binds = payload[:binds]

        if binds && !binds.empty?
          binds = binds.map { |col, val| val.inspect }
        end

        extracted_title, sql, binds, error = extract_binds(payload, binds)
        title = extracted_title if extracted_title

        if sql
          annotations = {
            sql:   sql,
            binds: binds,
          }
        else
          annotations = {
            skylight_error: error
          }
        end

        [ name, title, sql, annotations ]
      end

    private
      def extract_binds(payload, precalculated)
        title, sql, binds = SqlLexer::Lexer.bindify(payload[:sql], precalculated)
        [ title, sql, binds, nil ]
      rescue
        # Encode this since we may have improperly incoded strings that can't be to_json'ed
        encoded = encode(payload: payload, precalculated: precalculated)
        [ nil, nil, nil, ["sql_parse", encoded.to_json] ]
      end

      def encode(body)
        if body.is_a?(Hash)
          body.each{|k,v| body[k] = encode(v) }
        elsif body.is_a?(Array)
          body.each_with_index{|v,i| body[i] = encode(v) }
        elsif body.respond_to?(:encoding) && (body.encoding == Encoding::BINARY || !body.valid_encoding?)
          Base64.encode64(body)
        else
          body
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
skylight-0.2.2 lib/skylight/normalizers/sql.rb