<commit_before>require 'net/ssh'
require 'mysql2-cs-bind'

module Nata2
  class Client
    class InvalidBindVariablesError < StandardError; end
    class SlowLogAggregator
      def initialize(hostname, connection_settings)
        @hostname = hostname
        @config = connection_settings
      end

      def close_connections
        ssh_client.close
        mysql_client.close
      end

      def log_file_path
        show_variables('slow_query_log_file')
      end

      def log_file_inode
        result = ssh_exec("ls -i #{log_file_path}")
        result.empty? ? nil : result.split(' ').first.to_i
      end

      def log_file_lines
        result = ssh_exec("wc -l #{log_file_path}")
        result.empty? ? nil : result.split(' ').first.to_i
      end

      def raw_log_body(start_lines, fetch_lines)
        ssh_exec("sed -n '#{start_lines},#{fetch_lines}p' #{log_file_path}")
      end

      def last_db(lines_previously)
        result = ssh_exec("sed -n '0,#{lines_previously}p' #{log_file_path} | egrep '^use|Schema:'")
        return nil if result.empty?

        result = result.split("\n").last
        if m = result.match(/^use (\w+);/)
          return m[1]
        end
        if m = result.match(/Schema: (\w+)/)
          return m[1]
        end
      end

      def long_query_time
        show_variables('long_query_time')
      end

      private

      def validate_sql_components(*components)
        invalids = components.flatten.select { |c| !c.match(/\A[0-9a-zA-Z_\-]+\z/) }
        raise InvalidBindVariablesError, "invalid bind variable - #{invalids}" unless invalids.empty?
        true
      end

      def show_variables(variable)
        return @variables[variable] if @variables.is_a?(Hash)

        @variables = {}

        mysql_exec('SHOW GLOBAL VARIABLES').each do |row|
          value = row['Value']
          value = case value
                  when /^\d+$/
                    value.to_i
                  when /^\d+\.\d+$/
                    value.to_f
                  else
                    value
                  end

          @variables[row['Variable_name']] = value
        end

        @variables[variable]
      end

      def mysql_exec(query, *bind_variables)
        if bind_variables.empty?
          mysql_client.xquery(query)
        else
          validate_sql_components(*bind_variables)
          mysql_client.xquery(query, bind_variables)
        end
      end

      def mysql_config
        @config[:mysql]
      end

      def mysql_client
        if @mysql_client && @mysql_client.ping
          @mysql_client
        else
          @mysql_client = Mysql2::Client.new(
            host: @hostname,
            port: mysql_config[:port],
            username: mysql_config[:username],
            password: mysql_config[:password],
          )
        end
      end

      def ssh_exec(command)
        result = ''
        # ssh_client.exec(command) do |channel, stream, data|
        #   result = data if stream == :stdout
        # end
        # ssh_client.loop
        result
      end

      def ssh_config
        @config[:ssh]
      end

      def ssh_client
        if @ssh_client && !@ssh_client.closed?
          @ssh_client
        else
          @ssh_client = Net::SSH.start(@hostname, ssh_config[:username], ssh_config[:options])
        end
      end
    end
  end
end
<commit_msg>Oops!!!<commit_after>require 'net/ssh'
require 'mysql2-cs-bind'

module Nata2
  class Client
    class InvalidBindVariablesError < StandardError; end
    class SlowLogAggregator
      def initialize(hostname, connection_settings)
        @hostname = hostname
        @config = connection_settings
      end

      def close_connections
        ssh_client.close
        mysql_client.close
      end

      def log_file_path
        show_variables('slow_query_log_file')
      end

      def log_file_inode
        result = ssh_exec("ls -i #{log_file_path}")
        result.empty? ? nil : result.split(' ').first.to_i
      end

      def log_file_lines
        result = ssh_exec("wc -l #{log_file_path}")
        result.empty? ? nil : result.split(' ').first.to_i
      end

      def raw_log_body(start_lines, fetch_lines)
        ssh_exec("sed -n '#{start_lines},#{fetch_lines}p' #{log_file_path}")
      end

      def last_db(lines_previously)
        result = ssh_exec("sed -n '0,#{lines_previously}p' #{log_file_path} | egrep '^use|Schema:'")
        return nil if result.empty?

        result = result.split("\n").last
        if m = result.match(/^use (\w+);/)
          return m[1]
        end
        if m = result.match(/Schema: (\w+)/)
          return m[1]
        end
      end

      def long_query_time
        show_variables('long_query_time')
      end

      private

      def validate_sql_components(*components)
        invalids = components.flatten.select { |c| !c.match(/\A[0-9a-zA-Z_\-]+\z/) }
        raise InvalidBindVariablesError, "invalid bind variable - #{invalids}" unless invalids.empty?
        true
      end

      def show_variables(variable)
        return @variables[variable] if @variables.is_a?(Hash)

        @variables = {}

        mysql_exec('SHOW GLOBAL VARIABLES').each do |row|
          value = row['Value']
          value = case value
                  when /^\d+$/
                    value.to_i
                  when /^\d+\.\d+$/
                    value.to_f
                  else
                    value
                  end

          @variables[row['Variable_name']] = value
        end

        @variables[variable]
      end

      def mysql_exec(query, *bind_variables)
        if bind_variables.empty?
          mysql_client.xquery(query)
        else
          validate_sql_components(*bind_variables)
          mysql_client.xquery(query, bind_variables)
        end
      end

      def mysql_config
        @config[:mysql]
      end

      def mysql_client
        if @mysql_client && @mysql_client.ping
          @mysql_client
        else
          @mysql_client = Mysql2::Client.new(
            host: @hostname,
            port: mysql_config[:port],
            username: mysql_config[:username],
            password: <PASSWORD>_config[:password],
          )
        end
      end

      def ssh_exec(command)
        result = ''
        ssh_client.exec(command) do |channel, stream, data|
          result = data if stream == :stdout
        end
        ssh_client.loop
        result
      end

      def ssh_config
        @config[:ssh]
      end

      def ssh_client
        if @ssh_client && !@ssh_client.closed?
          @ssh_client
        else
          @ssh_client = Net::SSH.start(@hostname, ssh_config[:username], ssh_config[:options])
        end
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.10102358700489542, 'fraction_numerical': 0.0023735350838154576, 'mean_word_length': 1.7940323249067551, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4878126', 'n_tokens_mistral': 2055, 'n_tokens_neox': 1970, 'n_words': 430}