textacular 5.2.0 → 5.5.1

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
  SHA256:
3
- metadata.gz: f9a8ae35c8edfea5bfe856e76614e2689eed90d4c41beee8a3271d1c3749586e
4
- data.tar.gz: 4e88e50d311cdbccf5aae2fc71f0c3ef2d0af22b284a5bb772c7687f311eb50b
3
+ metadata.gz: eddfcccc0eaadfc3ac88a01770041972e58ec6f15d040fc2edd0d86622b520ac
4
+ data.tar.gz: 7d726e410c01a0438f57424c051736d8b68df4371f6089794fd5da107fd661e6
5
5
  SHA512:
6
- metadata.gz: 3c5f2531575beb68748b2c4458ea7e4e57af212f901270c45e08c359c7e535c81f18a785ea95c8679e8a0be688472f4d798bdec0329212cb89d52789fae785ff
7
- data.tar.gz: '0811ce97f78f63a84d41f4576115a07b8b2f01896e8a2d3d9904ff293cf8b95235919a83c66ab02c3f81a9c48653f798bb59d1cd7facb03d0d1f7ba24a97ef1c'
6
+ metadata.gz: b0d0e8a14b67b814d84f1f897a7c4c93fe1c9f3f6be1e9ca4d9749ced7b521c13144e21b06753a4b60620a31c4434828e515e8581c9267aba2794039a8517c8b
7
+ data.tar.gz: 55591215dc23ed584e9d2117215e4090479c9fd9e0e5cbae20a8f580656b3256bb6fc636228b42682dca461d231a89edf469c067f408bbbaa9bb716842dc9e8b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 5.5.1
6
+
7
+ * Revert breaking change to fuzzy_search introduced in 49f09b389d2f2b18cbe9de565b7ac5fcac14d7c6
8
+
9
+ ## 5.5.0
10
+
11
+ * ActiveRecord 7.0 compatibility
12
+
13
+ ## 5.4.0
14
+
15
+ * ActiveRecord 6.1 compatibility
16
+
17
+ ## 5.3.0
18
+
19
+ * Add `#web_search` method to use Postgres' 11+ `websearch_to_tsquery`
20
+
5
21
  ## 5.2.0
6
22
 
7
23
  * Active Record 6.0 compatibility
data/Gemfile CHANGED
@@ -2,6 +2,13 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- git 'git://github.com/rails/rails.git', branch: 'master' do
5
+ git_source(:github) do |repo_name|
6
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
7
+ "https://github.com/#{repo_name}.git"
8
+ end
9
+
10
+ github 'rails/rails', branch: 'main' do
6
11
  gem 'activerecord'
7
12
  end
13
+
14
+ gem "pg", "~> 1.1"
data/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  # textacular
2
2
  [![Gem Version](http://img.shields.io/gem/v/textacular.svg)][rubygems]
3
- [![Build Status](https://img.shields.io/travis/textacular/textacular/master.svg)][travis]
3
+ [![Build Status](https://github.com/textacular/textacular/actions/workflows/main.yml/badge.svg)](https://github.com/textacular/textacular/actions/workflows/main.yml)
4
4
  [![Code Climate](https://img.shields.io/codeclimate/github/textacular/textacular.svg)][codeclimate]
5
5
 
6
6
  [rubygems]: http://rubygems.org/gems/textacular
7
- [travis]: https://travis-ci.org/textacular/textacular
8
7
  [codeclimate]: https://codeclimate.com/github/textacular/textacular
9
8
 
10
9
  Further documentation available at http://textacular.github.com/textacular.
@@ -19,26 +18,26 @@ extending ActiveRecord with scopes making search easy and fun!
19
18
  ## FEATURES/PROBLEMS:
20
19
 
21
20
  * Only works with PostgreSQL
21
+ * Anything that mucks with the `SELECT` statement (notably `pluck`), is likely
22
+ to [cause problems](https://github.com/textacular/textacular/issues/28).
22
23
 
23
24
 
24
25
  ## SYNOPSIS:
25
26
 
26
27
  ### Quick Start
27
28
 
28
- #### Rails 3, Rails 4
29
-
30
29
  In the project's Gemfile add
31
30
 
32
31
  ```ruby
33
- gem 'textacular', '~> 4.0'
32
+ gem 'textacular', '~> 5.0'
34
33
  ```
35
34
 
36
- #### Rails > 5.0
35
+ #### Rails 3, Rails 4
37
36
 
38
37
  In the project's Gemfile add
39
38
 
40
39
  ```ruby
41
- gem 'textacular', '~> 5.0'
40
+ gem 'textacular', '~> 4.0'
42
41
  ```
43
42
 
44
43
  #### ActiveRecord outside of Rails
@@ -75,6 +74,20 @@ Game.advanced_search(title: 'Street|Fantasy')
75
74
  Game.advanced_search(system: '!PS2')
76
75
  ```
77
76
 
77
+ The `#web_search` method lets you use Postgres' 11+ `websearch_to_tsquery` function
78
+ supporting websearch like syntax:
79
+
80
+ - unquoted text: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery.
81
+ - "quoted text": text inside quote marks will be converted to terms separated by <-> operators, as if processed by phraseto_tsquery.
82
+ - OR: logical or will be converted to the | operator.
83
+ - -: the logical not operator, converted to the the ! operator.
84
+
85
+ ```ruby
86
+ Game.web_search(title: '"Street Fantasy"')
87
+ Game.web_search(title: 'Street OR Fantasy')
88
+ Game.web_search(system: '-PS2')
89
+ ```
90
+
78
91
  Finally, the `#fuzzy_search` method lets you use Postgres's trigram search
79
92
  functionality.
80
93
 
@@ -150,29 +163,20 @@ migration add code like the following:
150
163
 
151
164
  #### For basic_search
152
165
  ```ruby
153
- execute "
154
- create index on email_logs using gin(to_tsvector('english', subject));
155
- create index on email_logs using gin(to_tsvector('english', email_address));"
166
+ add_index :email_logs, %{to_tsvector('english', subject)}, using: :gin
167
+ add_index :email_logs, %{to_tsvector('english', email_address)}, using: :gin
156
168
  ```
157
169
 
158
170
  #### For fuzzy_search
159
171
  ```ruby
160
- execute "
161
- CREATE INDEX trgm_subject_indx ON users USING gist (subject gist_trgm_ops);
162
- CREATE INDEX trgm_email_address_indx ON users USING gist (email_address gist_trgm_ops);
172
+ add_index :email_logs, :subject, using: :gist, opclass: :gist_trgm_ops
173
+ add_index :email_logs, :email_address, using: :gist, opclass: :gist_trgm_ops
163
174
  ```
164
175
 
165
176
  In the above example, the table email_logs has two text columns that we search against, subject and email_address.
166
177
  You will need to add an index for every text/string column you query against, or else Postgresql will revert to a
167
178
  full table scan instead of using the indexes.
168
179
 
169
- If you create these indexes, you should also switch to sql for your schema_format in `config/application.rb`:
170
-
171
- ```ruby
172
- config.active_record.schema_format = :sql
173
- ```
174
-
175
-
176
180
  ## REQUIREMENTS:
177
181
 
178
182
  * ActiveRecord
@@ -1,5 +1,5 @@
1
1
  module Textacular
2
- VERSION = '5.2.0'
2
+ VERSION = '5.5.1'
3
3
 
4
4
  def self.version
5
5
  VERSION
data/lib/textacular.rb CHANGED
@@ -37,6 +37,13 @@ module Textacular
37
37
  assemble_query(similarities, conditions, exclusive, rank_alias)
38
38
  end
39
39
 
40
+ def web_search(query = '', exclusive = true, rank_alias = nil)
41
+ exclusive, query = munge_exclusive_and_query(exclusive, query)
42
+ parsed_query_hash = parse_query_hash(query)
43
+ similarities, conditions = web_similarities_and_conditions(parsed_query_hash)
44
+ assemble_query(similarities, conditions, exclusive, rank_alias)
45
+ end
46
+
40
47
  private
41
48
 
42
49
  def munge_exclusive_and_query(exclusive, query)
@@ -120,6 +127,24 @@ module Textacular
120
127
  "(#{table_name}.#{column}::text % #{search_term})"
121
128
  end
122
129
 
130
+
131
+ def web_similarities_and_conditions(parsed_query_hash)
132
+ parsed_query_hash.inject([[], []]) do |(similarities, conditions), query_args|
133
+ similarities << web_similarity_string(*query_args)
134
+ conditions << web_condition_string(*query_args)
135
+
136
+ [similarities, conditions]
137
+ end
138
+ end
139
+
140
+ def web_similarity_string(table_name, column, search_term)
141
+ "COALESCE(ts_rank(to_tsvector(#{quoted_language}, #{table_name}.#{column}::text), websearch_to_tsquery(#{quoted_language}, #{search_term}::text)), 0)"
142
+ end
143
+
144
+ def web_condition_string(table_name, column, search_term)
145
+ "to_tsvector(#{quoted_language}, #{table_name}.#{column}::text) @@ websearch_to_tsquery(#{quoted_language}, #{search_term}::text)"
146
+ end
147
+
123
148
  def assemble_query(similarities, conditions, exclusive, rank_alias)
124
149
  rank_alias ||= 'rank' + rand(100000000000000000).to_s
125
150
  rank = connection.quote_column_name(rank_alias)
@@ -3,6 +3,6 @@ timeout: 5000
3
3
  host: localhost
4
4
  adapter: postgresql
5
5
  username: postgres
6
- password:
6
+ password: password
7
7
  database: textacular_test
8
- min_messages: ERROR
8
+ min_messages: ERROR
@@ -113,6 +113,14 @@ RSpec.describe "Searchable" do
113
113
  end
114
114
  end
115
115
 
116
+ describe "web search" do # Uses websearch_to_tsquery
117
+ ["hello \\", "tebow!" , "food &"].each do |search_term|
118
+ it "works with interesting term \"#{search_term}\"" do
119
+ expect(WebComicWithSearchableName.web_search(search_term)).to be_empty
120
+ end
121
+ end
122
+ end
123
+
116
124
  it "does fuzzy searching" do
117
125
  expect(
118
126
  WebComicWithSearchableName.fuzzy_search('Questio')
@@ -182,6 +190,14 @@ RSpec.describe "Searchable" do
182
190
  expect(
183
191
  WebComicWithSearchableNameAndAuthor.advanced_search("Tycho")
184
192
  ).to eq([penny_arcade])
193
+
194
+ expect(
195
+ WebComicWithSearchableNameAndAuthor.web_search("Penny")
196
+ ).to eq([penny_arcade])
197
+
198
+ expect(
199
+ WebComicWithSearchableNameAndAuthor.web_search("Tycho")
200
+ ).to eq([penny_arcade])
185
201
  end
186
202
 
187
203
  it "allows includes" do
@@ -218,6 +234,11 @@ RSpec.describe "Searchable" do
218
234
  search_result = WebComicWithSearchableNameAndAuthor.fuzzy_search('Questionable Content', true, 'my_rank')
219
235
  expect(search_result.first.attributes['my_rank']).to be_truthy
220
236
  end
237
+
238
+ it "is selected for web_search" do
239
+ search_result = WebComicWithSearchableNameAndAuthor.web_search('Questionable Content', true, 'my_rank')
240
+ expect(search_result.first.attributes['my_rank']).to be_truthy
241
+ end
221
242
  end
222
243
  end
223
244
  end
metadata CHANGED
@@ -1,32 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: textacular
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.0
4
+ version: 5.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Hamill
8
8
  - ecin
9
9
  - Aaron Patterson
10
10
  - Greg Molnar
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-08-20 00:00:00.000000000 Z
14
+ date: 2022-01-03 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: pg
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
- - - "~>"
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.0
22
+ version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - "~>"
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 1.0.0
29
+ version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rspec
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -120,7 +120,7 @@ dependencies:
120
120
  version: '5.0'
121
121
  - - "<"
122
122
  - !ruby/object:Gem::Version
123
- version: '6.1'
123
+ version: '7.1'
124
124
  type: :runtime
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
@@ -130,7 +130,7 @@ dependencies:
130
130
  version: '5.0'
131
131
  - - "<"
132
132
  - !ruby/object:Gem::Version
133
- version: '6.1'
133
+ version: '7.1'
134
134
  description: |-
135
135
  Textacular exposes full text search capabilities from PostgreSQL, extending
136
136
  ActiveRecord with scopes making search easy and fun!
@@ -154,7 +154,7 @@ files:
154
154
  - lib/textacular/tasks.rb
155
155
  - lib/textacular/trigram_installer.rb
156
156
  - lib/textacular/version.rb
157
- - spec/config.travis.yml
157
+ - spec/config.github.yml
158
158
  - spec/config.yml.example
159
159
  - spec/spec_helper.rb
160
160
  - spec/support/ar_stand_in.rb
@@ -179,7 +179,7 @@ homepage: http://textacular.github.com/textacular
179
179
  licenses:
180
180
  - MIT
181
181
  metadata: {}
182
- post_install_message:
182
+ post_install_message:
183
183
  rdoc_options: []
184
184
  require_paths:
185
185
  - lib
@@ -194,14 +194,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
194
  - !ruby/object:Gem::Version
195
195
  version: '0'
196
196
  requirements: []
197
- rubyforge_project:
198
- rubygems_version: 2.7.6
199
- signing_key:
197
+ rubygems_version: 3.1.4
198
+ signing_key:
200
199
  specification_version: 4
201
200
  summary: Textacular exposes full text search capabilities from PostgreSQL
202
201
  test_files:
203
202
  - spec/config.yml.example
204
- - spec/config.travis.yml
203
+ - spec/config.github.yml
205
204
  - spec/spec_helper.rb
206
205
  - spec/support/ar_stand_in.rb
207
206
  - spec/support/character.rb