pg_search 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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