<commit_before>module NetSuite
  module Support
    class SearchResult
      attr_accessor :response

      attr_reader :total_records
      attr_reader :total_pages
      attr_reader :current_page

      # header from a basic customer search:

      # <platformCore:searchResult xmlns:platformCore="urn:core_2012_1.platform.webservices.netsuite.com">
      #   <platformCore:status isSuccess="true"/>
      #   <platformCore:totalRecords>2770</platformCore:totalRecords>
      #   <platformCore:pageSize>5</platformCore:pageSize>
      #   <platformCore:totalPages>554</platformCore:totalPages>
      #   <platformCore:pageIndex>1</platformCore:pageIndex>
      #   <platformCore:searchId>WEBSERVICES_738944_SB2_03012013650784545962753432_28d96bd280</platformCore:searchId>

      def initialize(response, result_class)
        @result_class = result_class
        @response = response
        
        @total_records = response.body[:total_records].to_i
        @total_pages = response.body[:total_pages].to_i
        @current_page = response.body[:page_index].to_i

        if @total_records > 0
          if response.body.has_key?(:record_list)
            # basic search results
            record_list = response.body[:record_list][:record]
            record_list = [record_list] if @total_records == 1

            record_list.each do |record|
              results << result_class.new(record)
            end
          elsif response.body.has_key? :search_row_list
            # advanced search results
            record_list = response.body[:search_row_list][:search_row]
            record_list = [record_list] if @total_records == 1

            record_list.each do |record|
              # TODO because of customFieldList we need to either make this recursive
              #      or handle the customFieldList as a special case

              record.each_pair do |search_group, search_data|
                # skip all attributes: look for :basic and all :xxx_join
                next if search_group.to_s.start_with?('@')

                record[search_group].each_pair do |k, v|
                  # all return values are wrapped in a <SearchValue/>
                  # extract the value from <SearchValue/> to make results easier to work with

                  if v.is_a?(Hash) && v.has_key?(:search_value)
                    # search return values that are just internalIds are stored as attributes on the searchValue element
                    if v[:search_value].is_a?(Hash) && v[:search_value].has_key?(:'@internal_id')
                      record[search_group][k] = v[:search_value][:'@internal_id']
                    else
                      record[search_group][k] = v[:search_value]
                    end<commit_msg>Wrap search result in an array when there is only a single item in the results<commit_after>module NetSuite
  module Support
    class SearchResult
      attr_accessor :response

      attr_reader :total_records
      attr_reader :total_pages
      attr_reader :current_page

      # header from a basic customer search:

      # <platformCore:searchResult xmlns:platformCore="urn:core_2012_1.platform.webservices.netsuite.com">
      #   <platformCore:status isSuccess="true"/>
      #   <platformCore:totalRecords>2770</platformCore:totalRecords>
      #   <platformCore:pageSize>5</platformCore:pageSize>
      #   <platformCore:totalPages>554</platformCore:totalPages>
      #   <platformCore:pageIndex>1</platformCore:pageIndex>
      #   <platformCore:searchId>WEBSERVICES_738944_SB2_03012013650784545962753432_28d96bd280</platformCore:searchId>

      def initialize(response, result_class)
        @result_class = result_class
        @response = response
        
        @total_records = response.body[:total_records].to_i
        @total_pages = response.body[:total_pages].to_i
        @current_page = response.body[:page_index].to_i

        if @total_records > 0
          if response.body.has_key?(:record_list)
            # basic search results
            record_list = response.body[:record_list][:record]
            record_list = [record_list] unless record_list.is_a?(Array)

            record_list.each do |record|
              results << result_class.new(record)
            end
          elsif response.body.has_key? :search_row_list
            # advanced search results
            record_list = response.body[:search_row_list][:search_row]
            record_list = [record_list] unless record_list.is_a?(Array)

            record_list.each do |record|
              # TODO because of customFieldList we need to either make this recursive
              #      or handle the customFieldList as a special case

              record.each_pair do |search_group, search_data|
                # skip all attributes: look for :basic and all :xxx_join
                next if search_group.to_s.start_with?('@')

                record[search_group].each_pair do |k, v|
                  # all return values are wrapped in a <SearchValue/>
                  # extract the value from <SearchValue/> to make results easier to work with

                  if v.is_a?(Hash) && v.has_key?(:search_value)
                    # search return values that are just internalIds are stored as attributes on the searchValue element
                    if v[:search_value].is_a?(Hash) && v[:search_value].has_key?(:'@internal_id')
                      record[search_group][k] = v[:search_value][:'@internal_id']
                    else
                      record[search_group][k] = v[:search_value]
                    end
{'fraction_non_alphanumeric': 0.08522829006266786, 'fraction_numerical': 0.020053715308863025, 'mean_word_length': 2.4186046511627906, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '5884236', 'n_tokens_mistral': 1616, 'n_tokens_neox': 1509, 'n_words': 342}