pg_search 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 311af8f978ce0e6b2645afdac0013ccb0f7f68b6
4
- data.tar.gz: cd3dd95e45fc9f6db2e79ae20c9a126931478fd2
3
+ metadata.gz: e78424399f49c900c5be4aeb3d427323a8d5cb08
4
+ data.tar.gz: 5516d8fcc707711c41ebacff2cf013e04a3d0843
5
5
  SHA512:
6
- metadata.gz: 5a9c5bfe4fa3ffb60b6180ee74f536ca8539f55e21fbb420fbf73b0e719980df8effbfdd714f0b29255b7c403bd40fd1c75d86aa1670fef60a54dbda8bc7cef4
7
- data.tar.gz: 369fc0f80ef7a55613ab7a46cb0bf5cb9a40bce65e10d808880c8c4257cacf129cbb56d48827924f1481c87d6b446f6ae34aee92622d93bb75fcbd4337ca8415
6
+ metadata.gz: 2b953933148c7c760047cc7ef8d0d88ff1b6f5f79a5fde5899091a7eb8153e5df7162bda5bbac19304d2188f20564bff1da443551db0e7a23de17c27c66a5bc2
7
+ data.tar.gz: b8507bbc4567a7eedb31fbe9f7bf9f8412360efc1b4a5e52410425f9f59cb5e5f69c40e53c65e3c7789eca00412ffc9c7a04b90cecc320f4a877fd47154d12dc
@@ -7,17 +7,17 @@ AllCops:
7
7
  Style/StringLiterals:
8
8
  Enabled: false
9
9
 
10
- AllCops:
11
- Exclude:
12
- - bin/**/*
13
-
14
10
  Metrics/LineLength:
15
11
  Max: 120
16
12
 
17
13
  Metrics/MethodLength:
18
14
  Max: 21
19
15
 
20
- Style/AlignParameters:
16
+ Metrics/BlockLength:
17
+ Exclude:
18
+ - spec/**/*
19
+
20
+ Layout/AlignParameters:
21
21
  EnforcedStyle: with_fixed_indentation
22
22
 
23
23
  Style/HashSyntax:
@@ -1,183 +1,147 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2016-01-25 14:11:25 -0600 using RuboCop version 0.36.0.
3
+ # on 2017-07-21 13:18:24 -0500 using RuboCop version 0.49.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 2
10
- # Cop supports --auto-correct.
11
- Lint/UnneededDisable:
12
- Exclude:
13
- - 'lib/pg_search/features/tsearch.rb'
14
- - 'lib/pg_search/scope_options.rb'
15
-
16
- # Offense count: 1
17
- # Cop supports --auto-correct.
18
- Performance/Casecmp:
19
- Exclude:
20
- - 'spec/support/database.rb'
21
-
22
- # Offense count: 27
23
- Style/Documentation:
24
- Enabled: false
25
-
26
- # Offense count: 3
27
- # Cop supports --auto-correct.
28
- # Configuration parameters: EnforcedStyle, SupportedStyles.
29
- # SupportedStyles: when_needed, always
30
- Style/FrozenStringLiteralComment:
31
- Exclude:
32
- - 'lib/pg_search/migration/associated_against_generator.rb'
33
- - 'lib/pg_search/migration/dmetaphone_generator.rb'
34
- - 'lib/pg_search/version.rb'
35
-
36
- # Offense count: 1
37
- Style/IfInsideElse:
38
- Exclude:
39
- - 'lib/pg_search/multisearchable.rb'
40
-
41
9
  # Offense count: 26
42
10
  # Cop supports --auto-correct.
43
11
  # Configuration parameters: SupportedStyles, IndentationWidth.
44
12
  # SupportedStyles: special_inside_parentheses, consistent, align_brackets
45
- Style/IndentArray:
13
+ Layout/IndentArray:
46
14
  EnforcedStyle: consistent
47
15
 
48
16
  # Offense count: 3
49
17
  # Cop supports --auto-correct.
50
18
  # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
51
- # SupportedStyles: aligned, indented
52
- Style/MultilineMethodCallIndentation:
53
- Enabled: false
54
-
55
- # Offense count: 2
56
- # Cop supports --auto-correct.
57
- Style/MutableConstant:
19
+ # SupportedStyles: aligned, indented, indented_relative_to_receiver
20
+ Layout/MultilineMethodCallIndentation:
58
21
  Exclude:
59
- - 'lib/pg_search/configuration.rb'
60
- - 'lib/pg_search/scope_options.rb'
61
-
62
- # Offense count: 16
63
- # Cop supports --auto-correct.
64
- Style/NumericLiterals:
65
- MinDigits: 6
22
+ - 'spec/integration/pg_search_spec.rb'
66
23
 
67
24
  # Offense count: 1
68
25
  # Cop supports --auto-correct.
69
- Style/PerlBackrefs:
26
+ Layout/SpaceAfterComma:
70
27
  Exclude:
71
- - 'lib/pg_search/scope_options.rb'
28
+ - 'lib/pg_search/configuration.rb'
72
29
 
73
30
  # Offense count: 1
74
31
  # Cop supports --auto-correct.
75
- Style/Proc:
32
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
33
+ # SupportedStyles: space, no_space
34
+ Layout/SpaceAroundEqualsInParameterDefault:
76
35
  Exclude:
77
- - 'lib/pg_search/document.rb'
36
+ - 'lib/pg_search/multisearch.rb'
78
37
 
79
- # Offense count: 5
38
+ # Offense count: 3
39
+ # Cop supports --auto-correct.
80
40
  # Configuration parameters: EnforcedStyle, SupportedStyles.
81
- # SupportedStyles: compact, exploded
82
- Style/RaiseArgs:
83
- Enabled: false
41
+ # SupportedStyles: space, no_space
42
+ Layout/SpaceBeforeBlockBraces:
43
+ Exclude:
44
+ - 'lib/pg_search/features/tsearch.rb'
45
+ - 'spec/integration/pg_search_spec.rb'
84
46
 
85
- # Offense count: 1
47
+ # Offense count: 4
86
48
  # Cop supports --auto-correct.
87
- # Configuration parameters: AllowMultipleReturnValues.
88
- Style/RedundantReturn:
49
+ # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces, SpaceBeforeBlockParameters.
50
+ # SupportedStyles: space, no_space
51
+ # SupportedStylesForEmptyBraces: space, no_space
52
+ Layout/SpaceInsideBlockBraces:
89
53
  Exclude:
90
- - 'lib/pg_search/scope_options.rb'
54
+ - 'lib/pg_search/features/tsearch.rb'
55
+ - 'spec/integration/pg_search_spec.rb'
56
+ - 'spec/lib/pg_search_spec.rb'
91
57
 
92
- # Offense count: 11
58
+ # Offense count: 86
93
59
  # Cop supports --auto-correct.
94
- # Configuration parameters: EnforcedStyle, SupportedStyles.
95
- # SupportedStyles: only_raise, only_fail, semantic
96
- Style/SignalException:
60
+ # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SupportedStylesForEmptyBraces.
61
+ # SupportedStyles: space, no_space, compact
62
+ # SupportedStylesForEmptyBraces: space, no_space
63
+ Layout/SpaceInsideHashLiteralBraces:
97
64
  Exclude:
98
65
  - 'lib/pg_search.rb'
99
66
  - 'lib/pg_search/configuration.rb'
100
- - 'lib/pg_search/features/tsearch.rb'
101
- - 'lib/pg_search/multisearch/rebuilder.rb'
102
- - 'lib/pg_search/normalizer.rb'
103
- - 'lib/pg_search/scope_options.rb'
104
- - 'lib/pg_search/tasks.rb'
67
+ - 'lib/pg_search/document.rb'
68
+ - 'spec/integration/associations_spec.rb'
69
+ - 'spec/integration/pg_search_spec.rb'
70
+ - 'spec/lib/pg_search/configuration/association_spec.rb'
71
+ - 'spec/lib/pg_search/configuration/foreign_column_spec.rb'
72
+ - 'spec/lib/pg_search/features/tsearch_spec.rb'
73
+ - 'spec/lib/pg_search/multisearchable_spec.rb'
105
74
  - 'spec/lib/pg_search_spec.rb'
106
- - 'spec/support/database.rb'
107
75
 
108
- # Offense count: 2
76
+ # Offense count: 4
109
77
  # Cop supports --auto-correct.
110
- Style/SpaceAfterComma:
78
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
79
+ # SupportedStyles: final_newline, final_blank_line
80
+ Layout/TrailingBlankLines:
111
81
  Exclude:
112
- - 'lib/pg_search/configuration.rb'
113
- - 'lib/pg_search/tasks.rb'
82
+ - 'Guardfile'
83
+ - 'lib/pg_search/migration/multisearch_generator.rb'
84
+ - 'lib/pg_search/multisearch.rb'
85
+ - 'spec/integration/single_table_inheritance_spec.rb'
114
86
 
115
87
  # Offense count: 1
116
88
  # Cop supports --auto-correct.
117
- # Configuration parameters: EnforcedStyle, SupportedStyles.
118
- # SupportedStyles: space, no_space
119
- Style/SpaceAroundEqualsInParameterDefault:
120
- Enabled: false
89
+ Performance/Casecmp:
90
+ Exclude:
91
+ - 'spec/support/database.rb'
121
92
 
122
- # Offense count: 4
123
- # Cop supports --auto-correct.
124
- # Configuration parameters: EnforcedStyle, SupportedStyles.
125
- # SupportedStyles: space, no_space
126
- Style/SpaceBeforeBlockBraces:
93
+ # Offense count: 27
94
+ Style/Documentation:
127
95
  Enabled: false
128
96
 
129
- # Offense count: 3
97
+ # Offense count: 1
98
+ Style/IfInsideElse:
99
+ Exclude:
100
+ - 'lib/pg_search/multisearchable.rb'
101
+
102
+ # Offense count: 2
130
103
  # Cop supports --auto-correct.
131
- # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
132
- # SupportedStyles: space, no_space
133
- Style/SpaceInsideBlockBraces:
134
- Enabled: false
104
+ Style/MutableConstant:
105
+ Exclude:
106
+ - 'lib/pg_search/configuration.rb'
107
+ - 'lib/pg_search/scope_options.rb'
135
108
 
136
- # Offense count: 76
109
+ # Offense count: 1
137
110
  # Cop supports --auto-correct.
138
- # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
139
- # SupportedStyles: space, no_space
140
- Style/SpaceInsideHashLiteralBraces:
141
- Enabled: false
111
+ Style/PerlBackrefs:
112
+ Exclude:
113
+ - 'lib/pg_search/scope_options.rb'
142
114
 
143
- # Offense count: 2
115
+ # Offense count: 5
144
116
  # Cop supports --auto-correct.
145
- Style/SpaceInsideParens:
117
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
118
+ # SupportedStyles: compact, exploded
119
+ Style/RaiseArgs:
146
120
  Exclude:
147
- - 'spec/lib/pg_search/multisearch/rebuilder_spec.rb'
121
+ - 'lib/pg_search.rb'
122
+ - 'lib/pg_search/multisearch/rebuilder.rb'
123
+ - 'lib/pg_search/scope_options.rb'
148
124
 
149
- # Offense count: 3
125
+ # Offense count: 1
150
126
  # Cop supports --auto-correct.
151
- # Configuration parameters: SupportedStyles.
152
- # SupportedStyles: use_perl_names, use_english_names
153
- Style/SpecialGlobalVars:
154
- EnforcedStyle: use_english_names
127
+ # Configuration parameters: AllowMultipleReturnValues.
128
+ Style/RedundantReturn:
129
+ Exclude:
130
+ - 'lib/pg_search/scope_options.rb'
155
131
 
156
132
  # Offense count: 2
157
133
  # Cop supports --auto-correct.
158
134
  # Configuration parameters: IgnoredMethods.
159
- # IgnoredMethods: respond_to
135
+ # IgnoredMethods: respond_to, define_method
160
136
  Style/SymbolProc:
161
137
  Exclude:
162
138
  - 'lib/pg_search/features/feature.rb'
163
139
  - 'lib/pg_search/multisearch/rebuilder.rb'
164
140
 
165
- # Offense count: 5
166
- # Cop supports --auto-correct.
167
- # Configuration parameters: EnforcedStyle, SupportedStyles.
168
- # SupportedStyles: final_newline, final_blank_line
169
- Style/TrailingBlankLines:
170
- Exclude:
171
- - 'Guardfile'
172
- - 'lib/pg_search/extensions/arel.rb'
173
- - 'lib/pg_search/migration/multisearch_generator.rb'
174
- - 'lib/pg_search/multisearch.rb'
175
- - 'spec/integration/single_table_inheritance_spec.rb'
176
-
177
- # Offense count: 9
141
+ # Offense count: 10
178
142
  # Cop supports --auto-correct.
179
- # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
180
- # SupportedStyles: comma, consistent_comma, no_comma
143
+ # Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline.
144
+ # SupportedStylesForMultiline: comma, consistent_comma, no_comma
181
145
  Style/TrailingCommaInLiteral:
182
146
  Exclude:
183
147
  - 'spec/integration/pg_search_spec.rb'
@@ -2,35 +2,47 @@ language: ruby
2
2
  sudo: false
3
3
 
4
4
  rvm:
5
- - "2.3.3"
6
- - "2.2.6"
5
+ - "2.4.1"
6
+ - "2.3.4"
7
+ - "2.2.7"
7
8
  - "2.1.10"
8
- - jruby-9.1.6.0
9
+ - jruby-9.1.9.0
9
10
 
10
11
  env:
11
12
  - ACTIVE_RECORD_BRANCH="master"
13
+ - ACTIVE_RECORD_BRANCH="5-1-stable"
12
14
  - ACTIVE_RECORD_BRANCH="5-0-stable"
13
15
  - ACTIVE_RECORD_BRANCH="4-2-stable"
16
+ - ACTIVE_RECORD_VERSION="~> 5.1.0"
14
17
  - ACTIVE_RECORD_VERSION="~> 5.0.0"
15
- - ACTIVE_RECORD_VERSION="~> 4.2.0"
18
+ - ACTIVE_RECORD_VERSION="~> 4.2.9"
16
19
 
17
20
  matrix:
18
21
  allow_failures:
19
22
  - env: ACTIVE_RECORD_BRANCH="master"
23
+ - env: ACTIVE_RECORD_BRANCH="5-1-stable"
20
24
  - env: ACTIVE_RECORD_BRANCH="5-0-stable"
21
25
  - env: ACTIVE_RECORD_BRANCH="4-2-stable"
22
26
  exclude:
23
27
  - rvm: "2.1.10"
24
28
  env: ACTIVE_RECORD_BRANCH="master"
29
+ - rvm: "2.1.10"
30
+ env: ACTIVE_RECORD_BRANCH="5-1-stable"
25
31
  - rvm: "2.1.10"
26
32
  env: ACTIVE_RECORD_BRANCH="5-0-stable"
33
+ - rvm: "2.1.10"
34
+ env: ACTIVE_RECORD_VERSION="~> 5.1.0"
27
35
  - rvm: "2.1.10"
28
36
  env: ACTIVE_RECORD_VERSION="~> 5.0.0"
29
- - rvm: jruby-9.1.6.0
37
+ - rvm: jruby-9.1.9.0
30
38
  env: ACTIVE_RECORD_BRANCH="master"
31
- - rvm: jruby-9.1.6.0
39
+ - rvm: jruby-9.1.9.0
40
+ env: ACTIVE_RECORD_BRANCH="5-1-stable"
41
+ - rvm: jruby-9.1.9.0
32
42
  env: ACTIVE_RECORD_BRANCH="5-0-stable"
33
- - rvm: jruby-9.1.6.0
43
+ - rvm: jruby-9.1.9.0
44
+ env: ACTIVE_RECORD_VERSION="~> 5.1.0"
45
+ - rvm: jruby-9.1.9.0
34
46
  env: ACTIVE_RECORD_VERSION="~> 5.0.0"
35
47
 
36
48
  before_script:
@@ -1,12 +1,18 @@
1
1
  # pg_search changelog
2
2
 
3
+ ## 2.1.0
4
+
5
+ * Allow ts_headline options to be passed to :highlight (Ian Heisters)
6
+ * Wait to load PgSearch::Document until after Active Record has loaded (Logan Leger)
7
+ * Add Rails version to generated migrations (Erik Eide)
8
+
3
9
  ## 2.0.1
4
10
 
5
11
  * Remove require for generator that no longer exists. (Joshua Bartlett)
6
12
 
7
13
  ## 2.0.0
8
14
 
9
- * Drop support for PostgreSQL < 9.2.
15
+ * Drop support for PostgreSQL < 9.2.
10
16
  * Drop support for Active Record < 4.2.
11
17
  * Drop support for Ruby < 2.1.
12
18
  * Improve performance of has_one and belongs_to associations. (Peter Postma)
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'pg', :platform => :ruby
5
+ gem 'pg', '>= 0.21.0', :platform => :ruby
6
6
  gem "activerecord-jdbcpostgresql-adapter", ">= 1.3.1", :platform => :jruby
7
7
 
8
8
  if ENV['ACTIVE_RECORD_BRANCH']
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2016 Case Commons, Inc. <http://casecommons.org>
1
+ Copyright (c) 2010-2017 Case Commons, Inc. <http://casecommons.org>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -7,14 +7,14 @@
7
7
  [![Dependency Status](https://img.shields.io/gemnasium/Casecommons/pg_search.svg?style=flat)](https://gemnasium.com/Casecommons/pg_search)
8
8
  [![Inline docs](http://inch-ci.org/github/Casecommons/pg_search.svg?branch=master&style=flat)](http://inch-ci.org/github/Casecommons/pg_search)
9
9
  [![Join the chat at https://gitter.im/Casecommons/pg_search](https://img.shields.io/badge/gitter-join%20chat-blue.svg)](https://gitter.im/Casecommons/pg_search?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
10
- [![Stories in Ready](https://badge.waffle.io/Casecommons/pg_search.svg?label=ready&title=Ready)](https://waffle.io/Casecommons/pg_search)
10
+ [![Stories in Ready](https://img.shields.io/waffle/label/Casecommons/pg_search/in%20progress.svg)](https://waffle.io/Casecommons/pg_search)
11
11
 
12
12
  ## DESCRIPTION
13
13
 
14
14
  PgSearch builds named scopes that take advantage of PostgreSQL's full text
15
15
  search.
16
16
 
17
- Read the blog post introducing PgSearch at http://blog.pivotal.io/labs/labs/pg-search
17
+ Read the blog post introducing PgSearch at https://content.pivotal.io/blog/pg-search-how-i-learned-to-stop-worrying-and-love-postgresql-full-text-search
18
18
 
19
19
  ## REQUIREMENTS
20
20
 
@@ -703,12 +703,18 @@ Adding .with_pg_search_highlight after the pg_search_scope you can access to
703
703
  class Person < ActiveRecord::Base
704
704
  include PgSearch
705
705
  pg_search_scope :search,
706
- :against => :bio,
707
- :using => {
708
- :tsearch => {
709
- :highlight => {
710
- :start_sel => '<b>',
711
- :stop_sel => '</b>'
706
+ against: :bio,
707
+ using: {
708
+ tsearch: {
709
+ highlight: {
710
+ StartSel: '<start>',
711
+ StopSel: '<stop>',
712
+ MaxWords: 123,
713
+ MinWords: 456,
714
+ ShortWord: 4,
715
+ HighlightAll: true,
716
+ MaxFragments: 3,
717
+ FragmentDelimiter: '&hellip;'
712
718
  }
713
719
  }
714
720
  }
@@ -720,8 +726,13 @@ first_match = Person.search("Alberta").with_pg_search_highlight.first
720
726
  first_match.pg_search_highlight # => "Born in rural <b>Alberta</b>, where the buffalo roam."
721
727
  ```
722
728
 
723
- By default, it will add the delimiters `<b>` and `</b>` around the matched text. You can customize these delimiters and the number of fragments returned with the `:start_sel`, `stop_sel`, and `max_fragments` options.
729
+ The highlight option accepts all [options supported by
730
+ ts_headline](https://www.postgresql.org/docs/current/static/textsearch-controls.html),
731
+ and uses PostgreSQL's defaults.
724
732
 
733
+ See the
734
+ [documentation](https://www.postgresql.org/docs/current/static/textsearch-controls.html)
735
+ for details on the meaning of each option.
725
736
 
726
737
  #### :dmetaphone (Double Metaphone soundalike search)
727
738
 
@@ -1081,5 +1092,5 @@ Please read our [CONTRIBUTING guide](https://github.com/Casecommons/pg_search/bl
1081
1092
 
1082
1093
  ## LICENSE
1083
1094
 
1084
- Copyright © 2010–2016 [Case Commons, Inc](http://casecommons.org).
1095
+ Copyright © 2010–2017 [Case Commons, Inc](http://casecommons.org).
1085
1096
  Licensed under the MIT license, see [LICENSE](/LICENSE) file.
@@ -104,5 +104,8 @@ module PgSearch
104
104
  end
105
105
  end
106
106
 
107
- require "pg_search/document"
107
+ ActiveSupport.on_load(:active_record) do
108
+ require "pg_search/document"
109
+ end
110
+
108
111
  require "pg_search/railtie" if defined?(Rails)
@@ -54,7 +54,7 @@ module PgSearch
54
54
  end
55
55
 
56
56
  def singular_association?
57
- [:has_one, :belongs_to].include?(@model.reflect_on_association(@name).macro)
57
+ %i[has_one belongs_to].include?(@model.reflect_on_association(@name).macro)
58
58
  end
59
59
  end
60
60
  end
@@ -5,7 +5,7 @@ module PgSearch
5
5
  module Features
6
6
  class Feature
7
7
  def self.valid_options
8
- [:only, :sort_only]
8
+ %i[only sort_only]
9
9
  end
10
10
 
11
11
  delegate :connection, :quoted_table_name, :to => :'@model'
@@ -4,7 +4,7 @@ module PgSearch
4
4
  module Features
5
5
  class TSearch < Feature # rubocop:disable Metrics/ClassLength
6
6
  def self.valid_options
7
- super + [:dictionary, :prefix, :negation, :any_word, :normalization, :tsvector_column, :highlight]
7
+ super + %i[dictionary prefix negation any_word normalization tsvector_column highlight]
8
8
  end
9
9
 
10
10
  def conditions
@@ -24,22 +24,42 @@ module PgSearch
24
24
  private
25
25
 
26
26
  def ts_headline
27
- "ts_headline((#{document}), (#{tsquery}), '#{ts_headline_options}')"
27
+ Arel::Nodes::NamedFunction.new("ts_headline", [
28
+ dictionary,
29
+ arel_wrap(document),
30
+ arel_wrap(tsquery),
31
+ Arel::Nodes.build_quoted(ts_headline_options)
32
+ ]).to_sql
28
33
  end
29
34
 
30
35
  def ts_headline_options
31
- return nil unless options[:highlight].is_a?(Hash)
36
+ return '' unless options[:highlight].is_a?(Hash)
32
37
 
33
38
  headline_options = map_headline_options
34
- headline_options.map{|key, value| "#{key} = #{value}" if value }.compact.join(", ")
39
+ headline_options.map { |key, value| "#{key} = #{value}" unless value.nil? }.compact.join(", ")
35
40
  end
36
41
 
37
42
  def map_headline_options
38
- {
39
- "StartSel" => options[:highlight][:start_sel],
40
- "StopSel" => options[:highlight][:stop_sel],
41
- "MaxFragments" => options[:highlight][:max_fragments]
42
- }
43
+ indifferent_options = options.with_indifferent_access
44
+
45
+ %w[
46
+ StartSel StopSel MaxFragments MaxWords MinWords ShortWord FragmentDelimiter HighlightAll
47
+ ].reduce({}) do |hash, key|
48
+ hash.tap do
49
+ value = indifferent_options[:highlight][key]
50
+
51
+ hash[key] = case value
52
+ when String
53
+ %("#{value.gsub('"', '""')}")
54
+ when true
55
+ "TRUE"
56
+ when false
57
+ "FALSE"
58
+ else
59
+ value
60
+ end
61
+ end
62
+ end
43
63
  end
44
64
 
45
65
  DISALLOWED_TSQUERY_CHARACTERS = /['?\\:]/
@@ -114,7 +134,11 @@ module PgSearch
114
134
  end
115
135
 
116
136
  def tsearch_rank
117
- "ts_rank((#{tsdocument}), (#{tsquery}), #{normalization})"
137
+ Arel::Nodes::NamedFunction.new("ts_rank", [
138
+ arel_wrap(tsdocument),
139
+ arel_wrap(tsquery),
140
+ normalization
141
+ ]).to_sql
118
142
  end
119
143
 
120
144
  def dictionary
@@ -1,3 +1,4 @@
1
+ require 'active_record'
1
2
  require 'rails/generators/base'
2
3
 
3
4
  module PgSearch
@@ -13,7 +14,7 @@ module PgSearch
13
14
  def create_migration
14
15
  now = Time.now.utc
15
16
  filename = "#{now.strftime('%Y%m%d%H%M%S')}_#{migration_name}.rb"
16
- template "#{migration_name}.rb.erb", "db/migrate/#{filename}"
17
+ template "#{migration_name}.rb.erb", "db/migrate/#{filename}", migration_version
17
18
  end
18
19
 
19
20
  private
@@ -23,6 +24,14 @@ module PgSearch
23
24
  source_path = File.join(sql_directory, "#{filename}.sql")
24
25
  File.read(source_path).strip
25
26
  end
27
+
28
+ def migration_version
29
+ if ActiveRecord::VERSION::MAJOR >= 5
30
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
31
+ else
32
+ ""
33
+ end
34
+ end
26
35
  end
27
36
  end
28
37
  end
@@ -1,4 +1,4 @@
1
- class AddPgSearchDmetaphoneSupportFunctions < ActiveRecord::Migration
1
+ class AddPgSearchDmetaphoneSupportFunctions < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
3
  say_with_time("Adding support functions for pg_search :dmetaphone") do
4
4
  execute <<-'SQL'
@@ -1,4 +1,4 @@
1
- class CreatePgSearchDocuments < ActiveRecord::Migration
1
+ class CreatePgSearchDocuments < ActiveRecord::Migration<%= migration_version %>
2
2
  def self.up
3
3
  say_with_time("Creating table for pg_search multisearch") do
4
4
  create_table :pg_search_documents do |t|
@@ -4,7 +4,7 @@ require 'pg_search'
4
4
  namespace :pg_search do
5
5
  namespace :multisearch do
6
6
  desc "Rebuild PgSearch multisearch records for a given model"
7
- task :rebuild, [:model,:schema] => :environment do |_task, args|
7
+ task :rebuild, %i[model schema] => :environment do |_task, args|
8
8
  raise ArgumentError, <<-MESSAGE.strip_heredoc unless args.model
9
9
  You must pass a model as an argument.
10
10
  Example: rake pg_search:multisearch:rebuild[BlogPost]
@@ -1,3 +1,3 @@
1
1
  module PgSearch
2
- VERSION = "2.0.1".freeze
2
+ VERSION = "2.1.0".freeze
3
3
  end
@@ -1,4 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
+
2
3
  $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
4
  require 'pg_search/version'
4
5
 
@@ -25,7 +26,7 @@ Gem::Specification.new do |s|
25
26
  s.add_development_dependency 'pry'
26
27
  s.add_development_dependency 'rspec', '>= 3.3'
27
28
  s.add_development_dependency 'with_model', '>= 1.2'
28
- s.add_development_dependency 'rubocop', '>= 0.36'
29
+ s.add_development_dependency 'rubocop'
29
30
  s.add_development_dependency 'codeclimate-test-reporter'
30
31
  s.add_development_dependency 'simplecov'
31
32
 
@@ -283,7 +283,7 @@ describe PgSearch do
283
283
  include PgSearch
284
284
  belongs_to :another_model, :class_name => 'AssociatedModel'
285
285
 
286
- pg_search_scope :with_associated, :associated_against => {:another_model => [:title, :author]}
286
+ pg_search_scope :with_associated, :associated_against => {:another_model => %i[title author]}
287
287
  end
288
288
  end
289
289
 
@@ -329,14 +329,14 @@ describe PgSearch do
329
329
  with_model :Model do
330
330
  table do |t|
331
331
  t.integer 'number'
332
- t.belongs_to 'another_model'
332
+ t.belongs_to 'another_model', index: false
333
333
  end
334
334
 
335
335
  model do
336
336
  include PgSearch
337
- belongs_to :another_model, :class_name => 'AssociatedModel'
337
+ belongs_to :another_model, class_name: 'AssociatedModel'
338
338
 
339
- pg_search_scope :with_associated, :associated_against => {:another_model => :number}
339
+ pg_search_scope :with_associated, associated_against: {another_model: :number}
340
340
  end
341
341
  end
342
342
 
@@ -454,7 +454,7 @@ describe PgSearch do
454
454
 
455
455
  model do
456
456
  include PgSearch
457
- pg_search_scope :search, :against => :title, :using => [:tsearch, :trigram]
457
+ pg_search_scope :search, :against => :title, :using => %i[tsearch trigram]
458
458
  end
459
459
  end
460
460
 
@@ -495,7 +495,7 @@ describe PgSearch do
495
495
 
496
496
  model do
497
497
  include PgSearch
498
- pg_search_scope :search, :against => :title, :using => [:tsearch, :trigram]
498
+ pg_search_scope :search, :against => :title, :using => %i[tsearch trigram]
499
499
  end
500
500
  end
501
501
 
@@ -160,7 +160,7 @@ describe "an Active Record model which includes PgSearch" do
160
160
  expect(results.first.attributes.key?('content')).to eq false
161
161
 
162
162
  expect(results.select { |record| record.title == "bar" }).to eq [included]
163
- expect(results.select { |record| record.title != "bar" }).to be_empty
163
+ expect(results.reject { |record| record.title == "bar" }).to be_empty
164
164
  end
165
165
  end
166
166
 
@@ -177,7 +177,7 @@ describe "an Active Record model which includes PgSearch" do
177
177
  expect(results.first.attributes.key?('content')).to eq false
178
178
 
179
179
  expect(results.select { |record| record.title == "bar" }).to eq [included]
180
- expect(results.select { |record| record.title != "bar" }).to be_empty
180
+ expect(results.reject { |record| record.title == "bar" }).to be_empty
181
181
  end
182
182
  end
183
183
 
@@ -194,7 +194,7 @@ describe "an Active Record model which includes PgSearch" do
194
194
  expect(results.first.attributes.key?('content')).to eq false
195
195
 
196
196
  expect(results.select { |record| record.title == "bar" }).to eq [included]
197
- expect(results.select { |record| record.title != "bar" }).to be_empty
197
+ expect(results.reject { |record| record.title == "bar" }).to be_empty
198
198
  end
199
199
  end
200
200
 
@@ -465,7 +465,7 @@ describe "an Active Record model which includes PgSearch" do
465
465
  # WARNING: searching timestamps is not something PostgreSQL
466
466
  # full-text search is good at. Use at your own risk.
467
467
  pg_search_scope :search_timestamps,
468
- :against => [:created_at, :updated_at]
468
+ :against => %i[created_at updated_at]
469
469
  end
470
470
  end
471
471
 
@@ -481,7 +481,7 @@ describe "an Active Record model which includes PgSearch" do
481
481
 
482
482
  context "against multiple columns" do
483
483
  before do
484
- ModelWithPgSearch.pg_search_scope :search_title_and_content, :against => [:title, :content]
484
+ ModelWithPgSearch.pg_search_scope :search_title_and_content, :against => %i[title content]
485
485
  end
486
486
 
487
487
  it "returns rows whose columns contain all of the terms in the query across columns" do
@@ -520,7 +520,7 @@ describe "an Active Record model which includes PgSearch" do
520
520
 
521
521
  context "using trigram" do
522
522
  before do
523
- ModelWithPgSearch.pg_search_scope :with_trigrams, :against => [:title, :content], :using => :trigram
523
+ ModelWithPgSearch.pg_search_scope :with_trigrams, :against => %i[title content], :using => :trigram
524
524
  end
525
525
 
526
526
  it "returns rows where one searchable column and the query share enough trigrams" do
@@ -537,8 +537,8 @@ describe "an Active Record model which includes PgSearch" do
537
537
 
538
538
  context "when a threshold is specified" do
539
539
  before do
540
- ModelWithPgSearch.pg_search_scope :with_strict_trigrams, :against => [:title, :content], :using => {trigram: {threshold: 0.5}}
541
- ModelWithPgSearch.pg_search_scope :with_permissive_trigrams, :against => [:title, :content], :using => {trigram: {threshold: 0.1}}
540
+ ModelWithPgSearch.pg_search_scope :with_strict_trigrams, :against => %i[title content], :using => {trigram: {threshold: 0.5}}
541
+ ModelWithPgSearch.pg_search_scope :with_permissive_trigrams, :against => %i[title content], :using => {trigram: {threshold: 0.1}}
542
542
  end
543
543
 
544
544
  it "uses the threshold in the trigram expression" do
@@ -633,6 +633,33 @@ describe "an Active Record model which includes PgSearch" do
633
633
  expect(result.pg_search_highlight).to eq("Won't <b>Let</b> You Down")
634
634
  end
635
635
  end
636
+
637
+ context "with custom highlighting options" do
638
+ before do
639
+ ModelWithPgSearch.create! :content => "#{'text ' * 2}Let #{'text ' * 2}Let #{'text ' * 2}"
640
+
641
+ ModelWithPgSearch.pg_search_scope :search_content,
642
+ :against => :content,
643
+ :using => {
644
+ :tsearch => {
645
+ :highlight => {
646
+ :StartSel => '<mark class="highlight">',
647
+ :StopSel => '</mark>',
648
+ :FragmentDelimiter => '<delim class="my_delim">',
649
+ :MaxFragments => 2,
650
+ :MaxWords => 2,
651
+ :MinWords => 1
652
+ }
653
+ }
654
+ }
655
+ end
656
+
657
+ it "applies the options to the excerpts" do
658
+ result = ModelWithPgSearch.search_content("Let").with_pg_search_highlight.first
659
+
660
+ expect(result.pg_search_highlight).to eq(%(<mark class="highlight">Let</mark> text<delim class="my_delim"><mark class="highlight">Let</mark> text))
661
+ end
662
+ end
636
663
  end
637
664
 
638
665
  describe "ranking" do
@@ -744,7 +771,7 @@ describe "an Active Record model which includes PgSearch" do
744
771
  end
745
772
 
746
773
  it "returns all results containing any word in their title" do
747
- numbers = %w[one two three four].map{|number| ModelWithPgSearch.create!(:title => number)}
774
+ numbers = %w[one two three four].map { |number| ModelWithPgSearch.create!(:title => number) }
748
775
 
749
776
  results = ModelWithPgSearch.search_title_with_any_word("one two three four")
750
777
 
@@ -812,7 +839,7 @@ describe "an Active Record model which includes PgSearch" do
812
839
  context "using dmetaphone" do
813
840
  before do
814
841
  ModelWithPgSearch.pg_search_scope :with_dmetaphones,
815
- :against => [:title, :content],
842
+ :against => %i[title content],
816
843
  :using => :dmetaphone
817
844
  end
818
845
 
@@ -873,7 +900,7 @@ describe "an Active Record model which includes PgSearch" do
873
900
  ]
874
901
 
875
902
  ModelWithPgSearch.pg_search_scope :complex_search,
876
- :against => [:content, :title],
903
+ :against => %i[content title],
877
904
  :ignoring => :accents,
878
905
  :using => {
879
906
  :tsearch => {:dictionary => 'english'},
@@ -984,7 +1011,7 @@ describe "an Active Record model which includes PgSearch" do
984
1011
  unexpected.comments.create(body: 'commentwo')
985
1012
 
986
1013
  Post.pg_search_scope :search_by_content_with_tsvector,
987
- :associated_against => { comments: [:body] },
1014
+ :associated_against => {comments: [:body]},
988
1015
  :using => {
989
1016
  :tsearch => {
990
1017
  :tsvector_column => 'content_tsvector',
@@ -1071,7 +1098,7 @@ describe "an Active Record model which includes PgSearch" do
1071
1098
  with_model :AnotherModel do
1072
1099
  table do |t|
1073
1100
  t.string :content_tsvector # the type of the column doesn't matter
1074
- t.belongs_to :model_with_tsvector
1101
+ t.belongs_to :model_with_tsvector, index: false
1075
1102
  end
1076
1103
  end
1077
1104
 
@@ -1135,8 +1162,8 @@ describe "an Active Record model which includes PgSearch" do
1135
1162
 
1136
1163
  multiplied_result =
1137
1164
  ModelWithPgSearch.search_content_with_importance_as_rank_multiplier("foo")
1138
- .with_pg_search_rank
1139
- .first
1165
+ .with_pg_search_rank
1166
+ .first
1140
1167
 
1141
1168
  multiplied_rank = multiplied_result.pg_search_rank
1142
1169
 
@@ -1244,8 +1271,8 @@ describe "an Active Record model which includes PgSearch" do
1244
1271
  ModelWithPgSearch.pg_search_scope :search_content_ranked_by_dmetaphone,
1245
1272
  :against => :content,
1246
1273
  :using => {
1247
- :tsearch => { :any_word => true, :prefix => true },
1248
- :dmetaphone => { :any_word => true, :prefix => true, :sort_only => true }
1274
+ :tsearch => {:any_word => true, :prefix => true},
1275
+ :dmetaphone => {:any_word => true, :prefix => true, :sort_only => true}
1249
1276
  },
1250
1277
  :ranked_by => ":tsearch + (0.5 * :dmetaphone)"
1251
1278
 
@@ -11,12 +11,12 @@ describe PgSearch::Configuration::ForeignColumn do
11
11
  with_model :Model do
12
12
  table do |t|
13
13
  t.string "title"
14
- t.belongs_to :another_model
14
+ t.belongs_to :another_model, index: false
15
15
  end
16
16
 
17
17
  model do
18
18
  include PgSearch
19
- belongs_to :another_model, :class_name => 'AssociatedModel'
19
+ belongs_to :another_model, class_name: 'AssociatedModel'
20
20
 
21
21
  pg_search_scope :with_another, :associated_against => {:another_model => :title}
22
22
  end
@@ -63,10 +63,10 @@ describe PgSearch::Features::Trigram do
63
63
  end
64
64
  end
65
65
  context 'multiple columns' do
66
- let(:options) { { only: [:name, :content] } }
66
+ let(:options) { { only: %i[name content] } }
67
67
 
68
68
  it 'concatenates when multiples columns are selected' do
69
- options = { only: [:name, :content] }
69
+ options = { only: %i[name content] }
70
70
  expect(feature.conditions.to_sql).to eq("((#{coalesced_columns}) % '#{query}')")
71
71
  end
72
72
  end
@@ -93,7 +93,7 @@ describe PgSearch::Features::TSearch do
93
93
  PgSearch::Configuration::Column.new(:name, nil, Model),
94
94
  PgSearch::Configuration::Column.new(:content, nil, Model),
95
95
  ]
96
- options = { tsvector_column: "my_tsvector" }
96
+ options = {tsvector_column: "my_tsvector"}
97
97
  config = double(:config, :ignore => [])
98
98
  normalizer = PgSearch::Normalizer.new(config)
99
99
 
@@ -111,7 +111,7 @@ describe PgSearch::Features::TSearch do
111
111
  PgSearch::Configuration::Column.new(:name, nil, Model),
112
112
  PgSearch::Configuration::Column.new(:content, nil, Model),
113
113
  ]
114
- options = { tsvector_column: ["tsvector1", "tsvector2"] }
114
+ options = {tsvector_column: ["tsvector1", "tsvector2"]}
115
115
  config = double(:config, :ignore => [])
116
116
  normalizer = PgSearch::Normalizer.new(config)
117
117
 
@@ -122,4 +122,85 @@ describe PgSearch::Features::TSearch do
122
122
  end
123
123
  end
124
124
  end
125
+
126
+ describe "#highlight" do
127
+ with_model :Model do
128
+ table do |t|
129
+ t.string :name
130
+ t.text :content
131
+ end
132
+ end
133
+
134
+ it "generates SQL to call ts_headline" do
135
+ query = "query"
136
+ columns = [
137
+ PgSearch::Configuration::Column.new(:name, nil, Model)
138
+ ]
139
+ options = {}
140
+
141
+ config = double(:config, :ignore => [])
142
+ normalizer = PgSearch::Normalizer.new(config)
143
+
144
+ feature = described_class.new(query, options, columns, Model, normalizer)
145
+ expect(feature.highlight.to_sql).to eq(
146
+ "(ts_headline('simple', (coalesce(#{Model.quoted_table_name}.\"name\"::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), ''))"
147
+ )
148
+ end
149
+
150
+ context "when options[:dictionary] is passed" do
151
+ it 'uses the provided dictionary' do
152
+ query = "query"
153
+ columns = [
154
+ PgSearch::Configuration::Column.new(:name, nil, Model),
155
+ PgSearch::Configuration::Column.new(:content, nil, Model),
156
+ ]
157
+ options = {
158
+ dictionary: "spanish",
159
+ highlight: {
160
+ StartSel: "<b>",
161
+ StopSel: "</b>"
162
+ }
163
+ }
164
+
165
+ config = double(:config, :ignore => [])
166
+ normalizer = PgSearch::Normalizer.new(config)
167
+
168
+ feature = described_class.new(query, options, columns, Model, normalizer)
169
+
170
+ expected_sql = %{(ts_headline('spanish', (coalesce(#{Model.quoted_table_name}."name"::text, '') || ' ' || coalesce(#{Model.quoted_table_name}."content"::text, '')), (to_tsquery('spanish', ''' ' || 'query' || ' ''')), 'StartSel = "<b>", StopSel = "</b>"'))}
171
+
172
+ expect(feature.highlight.to_sql).to eq(expected_sql)
173
+ end
174
+ end
175
+
176
+ context "when options[:highlight] has options set" do
177
+ it "passes the options to ts_headline" do
178
+ query = "query"
179
+ columns = [
180
+ PgSearch::Configuration::Column.new(:name, nil, Model)
181
+ ]
182
+ options = {
183
+ highlight: {
184
+ StartSel: '<start class="search">',
185
+ StopSel: '<stop>',
186
+ MaxWords: 123,
187
+ MinWords: 456,
188
+ ShortWord: 4,
189
+ HighlightAll: true,
190
+ MaxFragments: 3,
191
+ FragmentDelimiter: '&hellip;'
192
+ }
193
+ }
194
+
195
+ config = double(:config, :ignore => [])
196
+ normalizer = PgSearch::Normalizer.new(config)
197
+
198
+ feature = described_class.new(query, options, columns, Model, normalizer)
199
+
200
+ expected_sql = %{(ts_headline('simple', (coalesce(#{Model.quoted_table_name}."name"::text, '')), (to_tsquery('simple', ''' ' || 'query' || ' ''')), 'StartSel = "<start class=""search"">", StopSel = "<stop>", MaxFragments = 3, MaxWords = 123, MinWords = 456, ShortWord = 4, FragmentDelimiter = "&hellip;", HighlightAll = TRUE'))}
201
+
202
+ expect(feature.highlight.to_sql).to eq(expected_sql)
203
+ end
204
+ end
205
+ end
125
206
  end
@@ -42,7 +42,7 @@ describe PgSearch::Multisearch::Rebuilder do
42
42
  end
43
43
 
44
44
  context "and multisearchable is conditional" do
45
- [:if, :unless].each do |conditional_key|
45
+ %i[if unless].each do |conditional_key|
46
46
  context "via :#{conditional_key}" do
47
47
  with_model :Model do
48
48
  table do |t|
@@ -139,7 +139,7 @@ describe PgSearch::Multisearch do
139
139
 
140
140
  context "with multiple attributes" do
141
141
  before do
142
- model.multisearchable :against => [:title, :content]
142
+ model.multisearchable :against => %i[title content]
143
143
  end
144
144
 
145
145
  it "should generate the proper SQL code" do
@@ -118,7 +118,7 @@ describe PgSearch::Multisearchable do
118
118
  end
119
119
 
120
120
  context "when searching against multiple columns" do
121
- let(:multisearchable_options) { {:against => [:attr1, :attr2]} }
121
+ let(:multisearchable_options) { {:against => %i[attr1 attr2]} }
122
122
  before do
123
123
  allow(record).to receive(:attr1) { '1' }
124
124
  allow(record).to receive(:attr2) { '2' }
@@ -155,7 +155,7 @@ describe PgSearch::Multisearchable do
155
155
  end
156
156
 
157
157
  context "when searching against multiple columns" do
158
- let(:multisearchable_options) { {:against => [:attr1, :attr2]} }
158
+ let(:multisearchable_options) { {:against => %i[attr1 attr2]} }
159
159
  before do
160
160
  allow(record).to receive(:attr1) { '1' }
161
161
  allow(record).to receive(:attr2) { '2' }
@@ -3,7 +3,7 @@ if defined? JRUBY_VERSION
3
3
  error_classes = [ActiveRecord::JDBCError]
4
4
  else
5
5
  require "pg"
6
- error_classes = [PGError]
6
+ error_classes = [PG::Error]
7
7
  end
8
8
 
9
9
  error_classes << ActiveRecord::NoDatabaseError if defined? ActiveRecord::NoDatabaseError
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Grant Hutchins
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-12-20 00:00:00.000000000 Z
12
+ date: 2017-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -115,14 +115,14 @@ dependencies:
115
115
  requirements:
116
116
  - - ">="
117
117
  - !ruby/object:Gem::Version
118
- version: '0.36'
118
+ version: '0'
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - ">="
124
124
  - !ruby/object:Gem::Version
125
- version: '0.36'
125
+ version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: codeclimate-test-reporter
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -241,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
241
  version: '0'
242
242
  requirements: []
243
243
  rubyforge_project:
244
- rubygems_version: 2.5.2
244
+ rubygems_version: 2.6.8
245
245
  signing_key:
246
246
  specification_version: 4
247
247
  summary: PgSearch builds Active Record named scopes that take advantage of PostgreSQL's