<commit_before>module FixtureBuilder
  class Builder
    include Delegations::Namer
    include Delegations::Configuration

    def initialize(configuration, namer, builder_block)
      @configuration = configuration
      @namer = namer
      @builder_block = builder_block
    end

    def generate!
      say "Building fixtures"
      clean_out_old_data
      create_fixture_objects
      names_from_ivars!
      write_data_to_files
      after_build.call if after_build
    end

    protected

    def create_fixture_objects
      load_legacy_fixtures if legacy_fixtures.present?
      surface_errors { instance_eval &@builder_block }
    end

    def load_legacy_fixtures
      legacy_fixtures.each do |fixture_file|
        fixtures = fixtures_class.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
        populate_custom_names(fixtures)
      end
    end

    # Rails 3.0 and 3.1+ support
    def fixtures_class
      if defined?(ActiveRecord::FixtureSet)
        ActiveRecord::FixtureSet
      elsif defined?(ActiveRecord::Fixtures)
        ActiveRecord::Fixtures
      else
        ::Fixtures
      end
    end

    def surface_errors
      yield
    rescue Object => error
      puts
      say "There was an error building fixtures", error.inspect
      puts
      puts error.backtrace
      puts
      exit!
    end

    def names_from_ivars!
      instance_values.each do |var, value|
        name(var, value) if value.is_a? ActiveRecord::Base
      end
    end

    def write_data_to_files
      delete_yml_files
      dump_empty_fixtures_for_all_tables if write_empty_files
      dump_tables
    end

    def clean_out_old_data
      delete_tables
      delete_yml_files
    end

    def delete_tables
      ActiveRecord::Base.connection.disable_referential_integrity do
        tables.each { |t| ActiveRecord::Base.connection.delete(delete_sql % {table: ActiveRecord::Base.connection.quote_table_name(t)}) }
      end
    end

    def delete_yml_files
      FileUtils.rm(*tables.map { |t| fixture_file(t) }) rescue nil
    end

    def say(*messages)
      puts messages.map { |message| "=> #{message}" }
    end

    def dump_empty_fixtures_for_all_tables
      tables.each do |table_name|
        write_fixture_file({}, table_name)
      end
    end

    def dump_tables
      default_date_format = Date::DATE_FORMATS[:default]
      Date::DATE_FORMATS[:default] = Date::DATE_FORMATS[:db]
      begin
        fixtures = tables.inject([]) do |files, table_name|
          table_klass = table_name.classify.constantize rescue nil
          if table_klass && table_klass < ActiveRecord::Base
            rows = table_klass.unscoped do
              table_klass.all.collect do |obj|
                attrs = obj.attributes.select { |attr_name| table_klass.column_names.include?(attr_name) }
                attrs.inject({}) do |hash, (attr_name, value)|<commit_msg>Stabilize order of records in YAML files<commit_after>module FixtureBuilder
  class Builder
    include Delegations::Namer
    include Delegations::Configuration

    def initialize(configuration, namer, builder_block)
      @configuration = configuration
      @namer = namer
      @builder_block = builder_block
    end

    def generate!
      say "Building fixtures"
      clean_out_old_data
      create_fixture_objects
      names_from_ivars!
      write_data_to_files
      after_build.call if after_build
    end

    protected

    def create_fixture_objects
      load_legacy_fixtures if legacy_fixtures.present?
      surface_errors { instance_eval &@builder_block }
    end

    def load_legacy_fixtures
      legacy_fixtures.each do |fixture_file|
        fixtures = fixtures_class.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*'))
        populate_custom_names(fixtures)
      end
    end

    # Rails 3.0 and 3.1+ support
    def fixtures_class
      if defined?(ActiveRecord::FixtureSet)
        ActiveRecord::FixtureSet
      elsif defined?(ActiveRecord::Fixtures)
        ActiveRecord::Fixtures
      else
        ::Fixtures
      end
    end

    def surface_errors
      yield
    rescue Object => error
      puts
      say "There was an error building fixtures", error.inspect
      puts
      puts error.backtrace
      puts
      exit!
    end

    def names_from_ivars!
      instance_values.each do |var, value|
        name(var, value) if value.is_a? ActiveRecord::Base
      end
    end

    def write_data_to_files
      delete_yml_files
      dump_empty_fixtures_for_all_tables if write_empty_files
      dump_tables
    end

    def clean_out_old_data
      delete_tables
      delete_yml_files
    end

    def delete_tables
      ActiveRecord::Base.connection.disable_referential_integrity do
        tables.each { |t| ActiveRecord::Base.connection.delete(delete_sql % {table: ActiveRecord::Base.connection.quote_table_name(t)}) }
      end
    end

    def delete_yml_files
      FileUtils.rm(*tables.map { |t| fixture_file(t) }) rescue nil
    end

    def say(*messages)
      puts messages.map { |message| "=> #{message}" }
    end

    def dump_empty_fixtures_for_all_tables
      tables.each do |table_name|
        write_fixture_file({}, table_name)
      end
    end

    def dump_tables
      default_date_format = Date::DATE_FORMATS[:default]
      Date::DATE_FORMATS[:default] = Date::DATE_FORMATS[:db]
      begin
        fixtures = tables.inject([]) do |files, table_name|
          table_klass = table_name.classify.constantize rescue nil
          if table_klass && table_klass < ActiveRecord::Base
            rows = table_klass.unscoped do
              table_klass.order(:id).all.collect do |obj|
                attrs = obj.attributes.select { |attr_name| table_klass.column_names.include?(attr_name) }
                attrs.inject({}) do |hash, (attr_name, value)|
{'fraction_non_alphanumeric': 0.07277075503928937, 'fraction_numerical': 0.0013665869490946361, 'mean_word_length': 2.7198221092757304, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2950724', 'n_tokens_mistral': 1773, 'n_tokens_neox': 1745, 'n_words': 379}