<commit_before>require 'open3'
require 'thor'
require 'cknife/config'

class CKnifePg < Thor

  no_tasks do
    def config
      @config ||= CKnife::Config
    end

    def conf
      @conf ||= {
        :host      => config['pg.host'] || "localhost",
        :port      => config['pg.port'] || 5432,
        :database  => config['pg.database'],
        :username  => config['pg.username'],
        :password  => config['<PASSWORD>']
      }
    end

    def connection_options
      "-h #{conf[:host]} -p #{conf[:port]} -U #{conf[:username]} --no-password"
    end

    # Leaves out options to simplify output.
    def psql_easy
      "psql #{connection_options} -d #{conf[:database]}"
    end

    def psql_invocation
      "#{psql_easy} --no-align --tuples-only"
    end

    def pg_pass_file
      @pg_pass_file = ".pgpass"
    end

    def dc(cmd)
      puts "PGPASSFILE=#{pg_pass_file} #{cmd}"
    end

    def pg_pass_file_execute(cmd, input = nil)
      return if !@session_ok
      dc(cmd) if options[:verbose]
      stdin, stdout, stderr, wait_thread = Open3.popen3({'PGPASSFILE' => pg_pass_file}, cmd)
      if input
        puts input if options[:verbose]
        stdin.write input
        stdin.close
      end
      output = stdout.read
      output += stderr.read
      $stdout.write output if options[:verbose]
      stdout.close
      stderr.close
      result = wait_thread.value.to_i
      @session_ok = @session_ok && (result == 0)

      # I'm not sure why I allow blocks to this method. 2018-10-09
      yield if block_given?
      output
    end

    def pg_str
      "#{conf[:host]}:#{conf[:port]}:*:#{conf[:username]}:#{conf[:password]}"
    end

    def write_pg_pass_file
      # pgpass format
      File.open(pg_pass_file, "w", 0600) { |f| f.write pg_str }
      pg_pass_file
    end

    def with_pg_pass_file
      if @session_live
        return yield
      end

      @session_live = true
      @session_ok = true

      existing_pgpass = false
      if File.exists?(pg_pass_file)
        existing_pgpass = true
        s = File.read(pg_pass_file)
        if s != pg_str
          say("A .pgpass file is present, but it does not match your database configuration. The contents of the .pgpass file must exactly match what this tool would generate. Please reconcile the .pgpass file with your configuration, and then try again. You can also delete the .pgpass file since this tool generates one in order to do its job (and removes it after finishing).", :red)
          return
        end
      end

      write_pg_pass_file

      result = nil
      begin
        result = yield # don't know what we're planning to do with the result here...
      ensure
        if !existing_pgpass
          FileUtils.rm(pg_pass_file)
          if File.exists?(pg_pass_file)
            say("Failed to remove pg_pass file. Please remove it for security purposes.")
          end<commit_msg>inform the user when .pgpass file is left intact on disk.<commit_after>require 'open3'
require 'thor'
require 'cknife/config'

class CKnifePg < Thor

  no_tasks do
    def config
      @config ||= CKnife::Config
    end

    def conf
      @conf ||= {
        :host      => config['pg.host'] || "localhost",
        :port      => config['pg.port'] || 5432,
        :database  => config['pg.database'],
        :username  => config['pg.username'],
        :password  => config['pg.password']
      }
    end

    def connection_options
      "-h #{conf[:host]} -p #{conf[:port]} -U #{conf[:username]} --no-password"
    end

    # Leaves out options to simplify output.
    def psql_easy
      "psql #{connection_options} -d #{conf[:database]}"
    end

    def psql_invocation
      "#{psql_easy} --no-align --tuples-only"
    end

    def pg_pass_file
      @pg_pass_file = ".pgpass"
    end

    def dc(cmd)
      puts "PGPASSFILE=#{pg_pass_file} #{cmd}"
    end

    def pg_pass_file_execute(cmd, input = nil)
      return if !@session_ok
      dc(cmd) if options[:verbose]
      stdin, stdout, stderr, wait_thread = Open3.popen3({'PGPASSFILE' => pg_pass_file}, cmd)
      if input
        puts input if options[:verbose]
        stdin.write input
        stdin.close
      end
      output = stdout.read
      output += stderr.read
      $stdout.write output if options[:verbose]
      stdout.close
      stderr.close
      result = wait_thread.value.to_i
      @session_ok = @session_ok && (result == 0)

      # I'm not sure why I allow blocks to this method. 2018-10-09
      yield if block_given?
      output
    end

    def pg_str
      "#{conf[:host]}:#{conf[:port]}:*:#{conf[:username]}:#{conf[:password]}"
    end

    def write_pg_pass_file
      # pgpass format
      File.open(pg_pass_file, "w", 0600) { |f| f.write pg_str }
      pg_pass_file
    end

    def with_pg_pass_file
      if @session_live
        return yield
      end

      @session_live = true
      @session_ok = true

      existing_pgpass = false
      if File.exists?(pg_pass_file)
        existing_pgpass = true
        s = File.read(pg_pass_file)
        if s != pg_str
          say("A .pgpass file is present, but it does not match your database configuration. The contents of the .pgpass file must exactly match what this tool would generate. Please reconcile the .pgpass file with your configuration, and then try again. You can also delete the .pgpass file since this tool generates one in order to do its job (and removes it after finishing).", :red)
          return
        end
      end

      write_pg_pass_file

      result = nil
      begin
        result = yield # don't know what we're planning to do with the result here...
      ensure
        if !existing_pgpass
          FileUtils.rm(pg_pass_file)
          if File.exists?(pg_pass_file)
            say("Failed to remove .pgpass file. Please remove it for your infrastructure's security.")
          end
        else
          say("Left existing .pgpass file on disk.", :yellow)
{'fraction_non_alphanumeric': 0.10344827586206896, 'fraction_numerical': 0.00672834314550042, 'mean_word_length': 2.2706270627062706, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 16, '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': '1323215', 'n_tokens_mistral': 1886, 'n_tokens_neox': 1814, 'n_words': 558}