lib/pg_search/features/tsearch.rb in pg_search-2.0.1 vs lib/pg_search/features/tsearch.rb in pg_search-2.1.0

- old
+ new

@@ -2,11 +2,11 @@ module PgSearch module Features class TSearch < Feature # rubocop:disable Metrics/ClassLength def self.valid_options - super + [:dictionary, :prefix, :negation, :any_word, :normalization, :tsvector_column, :highlight] + super + %i[dictionary prefix negation any_word normalization tsvector_column highlight] end def conditions Arel::Nodes::Grouping.new( Arel::Nodes::InfixOperation.new("@@", arel_wrap(tsdocument), arel_wrap(tsquery)) @@ -22,26 +22,46 @@ end private def ts_headline - "ts_headline((#{document}), (#{tsquery}), '#{ts_headline_options}')" + Arel::Nodes::NamedFunction.new("ts_headline", [ + dictionary, + arel_wrap(document), + arel_wrap(tsquery), + Arel::Nodes.build_quoted(ts_headline_options) + ]).to_sql end def ts_headline_options - return nil unless options[:highlight].is_a?(Hash) + return '' unless options[:highlight].is_a?(Hash) headline_options = map_headline_options - headline_options.map{|key, value| "#{key} = #{value}" if value }.compact.join(", ") + headline_options.map { |key, value| "#{key} = #{value}" unless value.nil? }.compact.join(", ") end def map_headline_options - { - "StartSel" => options[:highlight][:start_sel], - "StopSel" => options[:highlight][:stop_sel], - "MaxFragments" => options[:highlight][:max_fragments] - } + indifferent_options = options.with_indifferent_access + + %w[ + StartSel StopSel MaxFragments MaxWords MinWords ShortWord FragmentDelimiter HighlightAll + ].reduce({}) do |hash, key| + hash.tap do + value = indifferent_options[:highlight][key] + + hash[key] = case value + when String + %("#{value.gsub('"', '""')}") + when true + "TRUE" + when false + "FALSE" + else + value + end + end + end end DISALLOWED_TSQUERY_CHARACTERS = /['?\\:]/ def tsquery_for_term(unsanitized_term) # rubocop:disable Metrics/AbcSize @@ -112,10 +132,14 @@ def normalization options[:normalization] || 0 end def tsearch_rank - "ts_rank((#{tsdocument}), (#{tsquery}), #{normalization})" + Arel::Nodes::NamedFunction.new("ts_rank", [ + arel_wrap(tsdocument), + arel_wrap(tsquery), + normalization + ]).to_sql end def dictionary Arel::Nodes.build_quoted(options[:dictionary] || :simple) end