<commit_before>module Surus
  module JSON
    class Query
      attr_reader :original_scope
      attr_reader :options

      def initialize(original_scope, options={})
        @original_scope = original_scope
        @options = options
      end

      private
      def klass
        original_scope.klass
      end

      def subquery_sql
        select(columns.map(&:to_s).join(', ')).to_sql
      end

      def columns
        selected_columns + association_columns
      end

      def table_columns
        klass.columns
      end

      def selected_columns
        if options.key? :columns
          options[:columns]
        else
          table_columns.map do |c|
            "#{quoted_table_name}.#{connection.quote_column_name c.name}"
          end
        end
      end

      def association_columns
        included_associations_name_and_options.map do |association_name, association_options|
          association = klass.reflect_on_association association_name
          subquery = case association
          when ActiveRecord::Reflection::BelongsToReflection
            association_scope = BelongsToScopeBuilder.new(original_scope, association).scope
            RowQuery.new(association_scope, association_options).to_sql
          when ActiveRecord::Reflection::HasManyReflection
            association_scope = HasManyScopeBuilder.new(original_scope, association).scope
            ArrayAggQuery.new(association_scope, association_options).to_sql
          when ActiveRecord::Reflection::HasAndBelongsToManyReflection
            association_scope = HasAndBelongsToManyScopeBuilder.new(original_scope, association).scope
            ArrayAggQuery.new(association_scope, association_options).to_sql
          end
          "(#{subquery}) #{connection.quote_column_name association_name}"
        end
      end

      def included_associations_name_and_options
        _include = options[:include]
        if _include.nil?
          {}<commit_msg>Work with multiple rails versions<commit_after>module Surus
  module JSON
    class Query
      attr_reader :original_scope
      attr_reader :options

      def initialize(original_scope, options={})
        @original_scope = original_scope
        @options = options
      end

      private
      def klass
        original_scope.klass
      end

      def subquery_sql
        select(columns.map(&:to_s).join(', ')).to_sql
      end

      def columns
        selected_columns + association_columns
      end

      def table_columns
        klass.columns
      end

      def selected_columns
        if options.key? :columns
          options[:columns]
        else
          table_columns.map do |c|
            "#{quoted_table_name}.#{connection.quote_column_name c.name}"
          end
        end
      end

      def association_columns
        included_associations_name_and_options.map do |association_name, association_options|
          association = klass.reflect_on_association association_name

          # The way to get the association type is different in Rails 4.2 vs 4.0-4.1
          association_type = if defined? ActiveRecord::Reflection::BelongsToReflection
            # Rails 4.2+
            case association
            when ActiveRecord::Reflection::BelongsToReflection
              :belongs_to
            when ActiveRecord::Reflection::HasManyReflection
              :has_many
            when ActiveRecord::Reflection::HasAndBelongsToManyReflection
              :has_and_belongs_to_many
            end
          else
            # Rails 4.0-4.1
            association.source_macro
          end

          subquery = case association_type
          when :belongs_to
            association_scope = BelongsToScopeBuilder.new(original_scope, association).scope
            RowQuery.new(association_scope, association_options).to_sql
          when :has_many
            association_scope = HasManyScopeBuilder.new(original_scope, association).scope
            ArrayAggQuery.new(association_scope, association_options).to_sql
          when :has_and_belongs_to_many
            association_scope = HasAndBelongsToManyScopeBuilder.new(original_scope, association).scope
            ArrayAggQuery.new(association_scope, association_options).to_sql
          end
          "(#{subquery}) #{connection.quote_column_name association_name}"
        end
      end

      def included_associations_name_and_options
        _include = options[:include]
        if _include.nil?
          {}
{'fraction_non_alphanumeric': 0.06038324420677362, 'fraction_numerical': 0.00267379679144385, 'mean_word_length': 2.3525018670649738, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2723655', 'n_tokens_mistral': 1149, 'n_tokens_neox': 1141, 'n_words': 235}