search_cop 1.0.6 → 1.0.7
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 +7 -0
- data/.travis.yml +16 -5
- data/Appraisals +8 -7
- data/CHANGELOG.md +4 -0
- data/CONTRIBUTING.md +18 -0
- data/README.md +18 -9
- data/gemfiles/3.2.gemfile +2 -3
- data/gemfiles/4.0.gemfile +2 -3
- data/gemfiles/4.1.gemfile +2 -3
- data/gemfiles/4.2.gemfile +2 -3
- data/gemfiles/5.0.gemfile +25 -0
- data/lib/search_cop/version.rb +1 -1
- data/lib/search_cop/visitors/mysql.rb +5 -5
- data/lib/search_cop/visitors/postgres.rb +14 -6
- data/lib/search_cop/visitors/visitor.rb +2 -2
- data/lib/search_cop_grammar/attributes.rb +7 -3
- data/lib/search_cop_grammar/nodes.rb +6 -0
- data/lib/search_cop_grammar.rb +5 -5
- data/search_cop.gemspec +1 -1
- data/test/fulltext_test.rb +2 -2
- data/test/test_helper.rb +3 -3
- data/test/visitor_test.rb +5 -5
- metadata +27 -41
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a0cdde213f37d4e7a63dcca4a3d4ed4c3cf7b2aa
|
4
|
+
data.tar.gz: 52b11b8e9c1ecfbae19fd1f82d8a70f1eec08756
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 22dc719d4506c0036e0a39480f8e52785b2f985f33392f378d1dfc186dd0608d7d1c41c058c585251483dd403ffc197d6e8ba3e0184bf6eccb3456c54ac9fc2a
|
7
|
+
data.tar.gz: 5da7063ff0d1edadadae90ac08bb5b53754636b17152127c6f2b2c647526f3899587e88ce5d5879380f72a20813aaf4bba5195567e55cf6e8996b4bd8f9e8903
|
data/.travis.yml
CHANGED
@@ -7,18 +7,28 @@ before_script:
|
|
7
7
|
- psql -c 'create database search_cop;' -U postgres
|
8
8
|
|
9
9
|
rvm:
|
10
|
-
- 1.
|
11
|
-
- 2.
|
12
|
-
- 2.
|
13
|
-
- rbx-
|
10
|
+
- 2.1.10
|
11
|
+
- 2.2.5
|
12
|
+
- 2.3.1
|
13
|
+
- rbx-3
|
14
14
|
- jruby
|
15
15
|
env:
|
16
16
|
- DATABASE=sqlite
|
17
17
|
- DATABASE=mysql
|
18
18
|
- DATABASE=postgres
|
19
19
|
matrix:
|
20
|
+
include:
|
21
|
+
- rvm: 2.3.1
|
22
|
+
gemfile: gemfiles/5.0-Gemfile
|
23
|
+
env: DATABASE=sqlite
|
24
|
+
- rvm: 2.3.1
|
25
|
+
gemfile: gemfiles/5.0-Gemfile
|
26
|
+
env: DATABASE=mysql
|
27
|
+
- rvm: 2.3.1
|
28
|
+
gemfile: gemfiles/5.0-Gemfile
|
29
|
+
env: DATABASE=postgres
|
20
30
|
allow_failures:
|
21
|
-
- rvm: rbx-
|
31
|
+
- rvm: rbx-3
|
22
32
|
- rvm: jruby
|
23
33
|
|
24
34
|
gemfile:
|
@@ -31,4 +41,5 @@ install:
|
|
31
41
|
- "travis_retry bundle install"
|
32
42
|
|
33
43
|
script: "bundle exec rake test"
|
44
|
+
sudo: false
|
34
45
|
|
data/Appraisals
CHANGED
@@ -1,20 +1,21 @@
|
|
1
|
+
|
1
2
|
appraise "3.2" do
|
2
|
-
gem "activerecord", "~> 3.2
|
3
|
+
gem "activerecord", "~> 3.2"
|
3
4
|
gem "search_cop", :path => "../"
|
4
5
|
end
|
5
6
|
|
6
|
-
appraise "4.
|
7
|
-
gem "activerecord", "~> 4.
|
7
|
+
appraise "4.1" do
|
8
|
+
gem "activerecord", "~> 4.1"
|
8
9
|
gem "search_cop", :path => "../"
|
9
10
|
end
|
10
11
|
|
11
|
-
appraise "4.
|
12
|
-
gem "activerecord", "~> 4.
|
12
|
+
appraise "4.2" do
|
13
|
+
gem "activerecord", "~> 4.2"
|
13
14
|
gem "search_cop", :path => "../"
|
14
15
|
end
|
15
16
|
|
16
|
-
appraise "
|
17
|
-
gem "activerecord", "~>
|
17
|
+
appraise "5.0" do
|
18
|
+
gem "activerecord", "~> 5.0"
|
18
19
|
gem "search_cop", :path => "../"
|
19
20
|
end
|
20
21
|
|
data/CHANGELOG.md
CHANGED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
# Contributing
|
3
|
+
|
4
|
+
There are two ways to contribute: issues and pull requests.
|
5
|
+
|
6
|
+
## Issues
|
7
|
+
|
8
|
+
You are very welcome to submit a github issue in case you find a bug.
|
9
|
+
The more detailed, the easier to reproduce. So please be verbose.
|
10
|
+
|
11
|
+
## Pull Requests
|
12
|
+
|
13
|
+
1. Fork it
|
14
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
15
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
16
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
17
|
+
5. Create new Pull Request
|
18
|
+
|
data/README.md
CHANGED
@@ -36,14 +36,6 @@ Book.search(:or => [{:query => "Rowling -Potter"}, {:query => "Tolkien -Rings"}]
|
|
36
36
|
# ...
|
37
37
|
```
|
38
38
|
|
39
|
-
## AttrSearchable is now SearchCop
|
40
|
-
|
41
|
-
As the set of features of AttrSearchable grew and grew, it has been neccessary
|
42
|
-
to change its DSL and name, as no `attr_searchable` method is present anymore.
|
43
|
-
The new DSL is cleaner and more concise. Morever, the migration process is
|
44
|
-
simple. Please take a look into the migration guide
|
45
|
-
[MIGRATION.md](https://github.com/mrkamel/search_cop/blob/master/MIGRATION.md)
|
46
|
-
|
47
39
|
## Installation
|
48
40
|
|
49
41
|
For Rails/ActiveRecord 3 (or 4), add this line to your application's Gemfile:
|
@@ -255,6 +247,23 @@ Regarding compound indices for PostgreSQL, use:
|
|
255
247
|
ActiveRecord::Base.connection.execute "CREATE INDEX fulltext_index_books_on_title ON books USING GIN(to_tsvector('simple', author || ' ' || title))"
|
256
248
|
```
|
257
249
|
|
250
|
+
To handle NULL values with PostgreSQL correctly, use COALESCE both at index
|
251
|
+
creation time and when specifying the `search_scope`:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
ActiveRecord::Base.connection.execute "CREATE INDEX fulltext_index_books_on_title ON books USING GIN(to_tsvector('simple', COALESCE(author, '') || ' ' || COALESCE(title, '')))"
|
255
|
+
```
|
256
|
+
|
257
|
+
plus:
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
search_scope :search do
|
261
|
+
attributes :title
|
262
|
+
|
263
|
+
options :title, :type => :fulltext, coalesce: true
|
264
|
+
end
|
265
|
+
```
|
266
|
+
|
258
267
|
To use another PostgreSQL dictionary than `simple`, you have to create the
|
259
268
|
index accordingly and you need tell SearchCop about it, e.g.:
|
260
269
|
|
@@ -262,7 +271,7 @@ index accordingly and you need tell SearchCop about it, e.g.:
|
|
262
271
|
search_scope :search do
|
263
272
|
attributes :title
|
264
273
|
|
265
|
-
options :title, :type => :fulltext, :
|
274
|
+
options :title, :type => :fulltext, dictionary: "english"
|
266
275
|
end
|
267
276
|
```
|
268
277
|
|
data/gemfiles/3.2.gemfile
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "activerecord", "~> 3.2.
|
6
|
-
gem "search_cop", :path => "../"
|
5
|
+
gem "activerecord", "~> 3.2.22"
|
7
6
|
|
8
7
|
platforms :jruby do
|
9
8
|
gem "activerecord-jdbcmysql-adapter"
|
@@ -13,7 +12,7 @@ end
|
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
14
|
gem "sqlite3"
|
16
|
-
gem "mysql2"
|
15
|
+
gem "mysql2", "~> 0.3.20"
|
17
16
|
gem "pg"
|
18
17
|
end
|
19
18
|
|
data/gemfiles/4.0.gemfile
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "activerecord", "~> 4.0.
|
6
|
-
gem "search_cop", :path => "../"
|
5
|
+
gem "activerecord", "~> 4.0.13"
|
7
6
|
|
8
7
|
platforms :jruby do
|
9
8
|
gem "activerecord-jdbcmysql-adapter"
|
@@ -13,7 +12,7 @@ end
|
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
14
|
gem "sqlite3"
|
16
|
-
gem "mysql2"
|
15
|
+
gem "mysql2", "~> 0.3.20"
|
17
16
|
gem "pg"
|
18
17
|
end
|
19
18
|
|
data/gemfiles/4.1.gemfile
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "activerecord", "~> 4.1.
|
6
|
-
gem "search_cop", :path => "../"
|
5
|
+
gem "activerecord", "~> 4.1.13"
|
7
6
|
|
8
7
|
platforms :jruby do
|
9
8
|
gem "activerecord-jdbcmysql-adapter"
|
@@ -13,7 +12,7 @@ end
|
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
14
|
gem "sqlite3"
|
16
|
-
gem "mysql2"
|
15
|
+
gem "mysql2", "~> 0.3.20"
|
17
16
|
gem "pg"
|
18
17
|
end
|
19
18
|
|
data/gemfiles/4.2.gemfile
CHANGED
@@ -2,8 +2,7 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
gem "activerecord", "~> 4.2.
|
6
|
-
gem "search_cop", :path => "../"
|
5
|
+
gem "activerecord", "~> 4.2.4"
|
7
6
|
|
8
7
|
platforms :jruby do
|
9
8
|
gem "activerecord-jdbcmysql-adapter"
|
@@ -13,7 +12,7 @@ end
|
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
14
|
gem "sqlite3"
|
16
|
-
gem "mysql2"
|
15
|
+
gem "mysql2", "~> 0.3.20"
|
17
16
|
gem "pg"
|
18
17
|
end
|
19
18
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "activerecord", "~> 5.0"
|
6
|
+
|
7
|
+
platforms :jruby do
|
8
|
+
gem "activerecord-jdbcmysql-adapter"
|
9
|
+
gem "activerecord-jdbcsqlite3-adapter"
|
10
|
+
gem "activerecord-jdbcpostgresql-adapter"
|
11
|
+
end
|
12
|
+
|
13
|
+
platforms :ruby do
|
14
|
+
gem "sqlite3"
|
15
|
+
gem "mysql2", "~> 0.3.20"
|
16
|
+
gem "pg"
|
17
|
+
end
|
18
|
+
|
19
|
+
platforms :rbx do
|
20
|
+
gem "racc"
|
21
|
+
gem "rubysl", "~> 2.0"
|
22
|
+
gem "psych"
|
23
|
+
end
|
24
|
+
|
25
|
+
gemspec :path => "../"
|
data/lib/search_cop/version.rb
CHANGED
@@ -14,11 +14,11 @@ module SearchCop
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def visit_SearchCopGrammar_Nodes_And_Fulltext(node)
|
17
|
-
res = node.nodes.collect do |
|
18
|
-
if
|
19
|
-
visit
|
17
|
+
res = node.nodes.collect do |child_node|
|
18
|
+
if child_node.is_a?(SearchCopGrammar::Nodes::MatchesFulltextNot)
|
19
|
+
visit child_node
|
20
20
|
else
|
21
|
-
|
21
|
+
child_node.nodes.size > 1 ? "+(#{visit child_node})" : "+#{visit child_node}"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -26,7 +26,7 @@ module SearchCop
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def visit_SearchCopGrammar_Nodes_Or_Fulltext(node)
|
29
|
-
node.nodes.collect { |
|
29
|
+
node.nodes.collect { |child_node| "(#{visit child_node})" }.join(" ")
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -4,28 +4,36 @@ module SearchCop
|
|
4
4
|
module Postgres
|
5
5
|
class FulltextQuery < Visitor
|
6
6
|
def visit_SearchCopGrammar_Nodes_MatchesFulltextNot(node)
|
7
|
-
"!'#{node.right.gsub
|
7
|
+
"!'#{node.right.gsub(/[\s&|!:'"]+/, " ")}'"
|
8
8
|
end
|
9
9
|
|
10
10
|
def visit_SearchCopGrammar_Nodes_MatchesFulltext(node)
|
11
|
-
"'#{node.right.gsub
|
11
|
+
"'#{node.right.gsub(/[\s&|!:'"]+/, " ")}'"
|
12
12
|
end
|
13
13
|
|
14
14
|
def visit_SearchCopGrammar_Nodes_And_Fulltext(node)
|
15
|
-
node.nodes.collect { |
|
15
|
+
node.nodes.collect { |child_node| "(#{visit child_node})" }.join(" & ")
|
16
16
|
end
|
17
17
|
|
18
18
|
def visit_SearchCopGrammar_Nodes_Or_Fulltext(node)
|
19
|
-
node.nodes.collect { |
|
19
|
+
node.nodes.collect { |child_node| "(#{visit child_node})" }.join(" | ")
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def visit_SearchCopGrammar_Nodes_Matches(node)
|
24
|
-
"#{visit node.left} ILIKE #{visit node.right}"
|
24
|
+
"(#{visit node.left} IS NOT NULL AND #{visit node.left} ILIKE #{visit node.right})"
|
25
25
|
end
|
26
26
|
|
27
27
|
def visit_SearchCopGrammar_Attributes_Collection(node)
|
28
|
-
node.attributes.collect
|
28
|
+
res = node.attributes.collect do |attribute|
|
29
|
+
if attribute.options[:coalesce]
|
30
|
+
"COALESCE(#{visit attribute}, '')"
|
31
|
+
else
|
32
|
+
visit attribute
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
res.join(" || ' ' || ")
|
29
37
|
end
|
30
38
|
|
31
39
|
def visit_SearchCopGrammar_Nodes_FulltextExpression(node)
|
@@ -12,7 +12,7 @@ module SearchCop
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def visit(visit_node = node)
|
15
|
-
send "visit_#{visit_node.class.name.gsub
|
15
|
+
send "visit_#{visit_node.class.name.gsub(/::/, "_")}", visit_node
|
16
16
|
end
|
17
17
|
|
18
18
|
def visit_SearchCopGrammar_Nodes_And(node)
|
@@ -48,7 +48,7 @@ module SearchCop
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def visit_SearchCopGrammar_Nodes_Matches(node)
|
51
|
-
"#{visit node.left} LIKE #{visit node.right}"
|
51
|
+
"(#{visit node.left} IS NOT NULL AND #{visit node.left} LIKE #{visit node.right})"
|
52
52
|
end
|
53
53
|
|
54
54
|
def visit_SearchCopGrammar_Nodes_Not(node)
|
@@ -184,12 +184,14 @@ module SearchCopGrammar
|
|
184
184
|
::Time.new($1, $3, 15).beginning_of_month .. ::Time.new($1, $3, 15).end_of_month
|
185
185
|
elsif value =~ /^([0-9]{1,2})(\.|-|\/)([0-9]{4})$/
|
186
186
|
::Time.new($3, $1, 15).beginning_of_month .. ::Time.new($3, $1, 15).end_of_month
|
187
|
-
elsif value
|
187
|
+
elsif value =~ /^[0-9]{4}(\.|-|\/)[0-9]{1,2}(\.|-|\/)[0-9]{1,2}$/ || value =~ /^[0-9]{1,2}(\.|-|\/)[0-9]{1,2}(\.|-|\/)[0-9]{4}$/
|
188
188
|
time = ::Time.parse(value)
|
189
189
|
time.beginning_of_day .. time.end_of_day
|
190
|
-
|
190
|
+
elsif value =~ /[0-9]{4}(\.|-|\/)[0-9]{1,2}(\.|-|\/)[0-9]{1,2}/ || value =~ /[0-9]{1,2}(\.|-|\/)[0-9]{1,2}(\.|-|\/)[0-9]{4}/
|
191
191
|
time = ::Time.parse(value)
|
192
192
|
time .. time
|
193
|
+
else
|
194
|
+
raise ArgumentError
|
193
195
|
end
|
194
196
|
rescue ArgumentError
|
195
197
|
raise SearchCop::IncompatibleDatatype, "Incompatible datatype for #{value}"
|
@@ -228,9 +230,11 @@ module SearchCopGrammar
|
|
228
230
|
::Date.new($1.to_i, $3.to_i, 15).beginning_of_month .. ::Date.new($1.to_i, $3.to_i, 15).end_of_month
|
229
231
|
elsif value =~ /^([0-9]{1,2})(\.|-|\/)([0-9]{4})$/
|
230
232
|
::Date.new($3.to_i, $1.to_i, 15).beginning_of_month .. ::Date.new($3.to_i, $1.to_i, 15).end_of_month
|
231
|
-
|
233
|
+
elsif value =~ /[0-9]{4}(\.|-|\/)[0-9]{1,2}(\.|-|\/)[0-9]{1,2}/ || value =~ /[0-9]{1,2}(\.|-|\/)[0-9]{1,2}(\.|-|\/)[0-9]{4}/
|
232
234
|
date = ::Date.parse(value)
|
233
235
|
date .. date
|
236
|
+
else
|
237
|
+
raise ArgumentError
|
234
238
|
end
|
235
239
|
rescue ArgumentError
|
236
240
|
raise SearchCop::IncompatibleDatatype, "Incompatible datatype for #{value}"
|
data/lib/search_cop_grammar.rb
CHANGED
@@ -7,7 +7,7 @@ module SearchCopGrammar
|
|
7
7
|
attr_accessor :query_info
|
8
8
|
|
9
9
|
def query_info
|
10
|
-
@query_info || parent.query_info
|
10
|
+
(@query_info ||= nil) || parent.query_info
|
11
11
|
end
|
12
12
|
|
13
13
|
def evaluate
|
@@ -94,13 +94,13 @@ module SearchCopGrammar
|
|
94
94
|
|
95
95
|
class SingleQuotedAnywhereExpression < AnywhereExpression
|
96
96
|
def text_value
|
97
|
-
super.gsub
|
97
|
+
super.gsub(/^'|'$/, "")
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
101
|
class DoubleQuotedAnywhereExpression < AnywhereExpression
|
102
102
|
def text_value
|
103
|
-
super.gsub
|
103
|
+
super.gsub(/^"|"$/, "")
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -130,13 +130,13 @@ module SearchCopGrammar
|
|
130
130
|
|
131
131
|
class SingleQuotedValue < BaseNode
|
132
132
|
def text_value
|
133
|
-
super.gsub
|
133
|
+
super.gsub(/^'|'$/, "")
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
137
|
class DoubleQuotedValue < BaseNode
|
138
138
|
def text_value
|
139
|
-
super.gsub
|
139
|
+
super.gsub(/^"|"$/, "")
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
data/search_cop.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "treetop"
|
22
22
|
|
23
|
-
spec.add_development_dependency "bundler"
|
23
|
+
spec.add_development_dependency "bundler"
|
24
24
|
spec.add_development_dependency "rake"
|
25
25
|
spec.add_development_dependency "activerecord", ">= 3.0.0"
|
26
26
|
spec.add_development_dependency "factory_girl"
|
data/test/fulltext_test.rb
CHANGED
@@ -7,7 +7,7 @@ class FulltextTest < SearchCop::TestCase
|
|
7
7
|
product2 = create(:product, :title => "word2 word3")
|
8
8
|
product3 = create(:product, :title => "word2")
|
9
9
|
|
10
|
-
results = Product.search("
|
10
|
+
results = Product.search("word1 OR (title:word2 -word3)")
|
11
11
|
|
12
12
|
assert_includes results, product1
|
13
13
|
refute_includes results, product2
|
@@ -18,7 +18,7 @@ class FulltextTest < SearchCop::TestCase
|
|
18
18
|
expected = create(:product, :title => "Expected title", :stock => 1)
|
19
19
|
rejected = create(:product, :title => "Expected title", :stock => 0)
|
20
20
|
|
21
|
-
results = Product.search("
|
21
|
+
results = Product.search("Expected title:Title stock > 0")
|
22
22
|
|
23
23
|
assert_includes results, expected
|
24
24
|
refute_includes results, rejected
|
data/test/test_helper.rb
CHANGED
@@ -44,9 +44,9 @@ class Product < ActiveRecord::Base
|
|
44
44
|
aliases :users_products => :user
|
45
45
|
|
46
46
|
if DATABASE != "sqlite"
|
47
|
-
options :title, :type => :fulltext
|
48
|
-
options :description, :type => :fulltext
|
49
|
-
options :comment, :type => :fulltext
|
47
|
+
options :title, :type => :fulltext, coalesce: true
|
48
|
+
options :description, :type => :fulltext, coalesce: true
|
49
|
+
options :comment, :type => :fulltext, coalesce: true
|
50
50
|
end
|
51
51
|
|
52
52
|
if DATABASE == "postgres"
|
data/test/visitor_test.rb
CHANGED
@@ -53,8 +53,8 @@ class VisitorTest < SearchCop::TestCase
|
|
53
53
|
def test_matches
|
54
54
|
node = SearchCopGrammar::Attributes::String.new(Product, "products", "notice").matches("Notice")
|
55
55
|
|
56
|
-
assert_equal("#{quote_table_name "products"}.#{quote_column_name "notice"} LIKE #{quote "%Notice%"}", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] != "postgres"
|
57
|
-
assert_equal("#{quote_table_name "products"}.#{quote_column_name "notice"} ILIKE #{quote "%Notice%"}", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
56
|
+
assert_equal("(#{quote_table_name "products"}.#{quote_column_name "notice"} IS NOT NULL AND #{quote_table_name "products"}.#{quote_column_name "notice"} LIKE #{quote "%Notice%"})", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] != "postgres"
|
57
|
+
assert_equal("(#{quote_table_name "products"}.#{quote_column_name "notice"} IS NOT NULL AND #{quote_table_name "products"}.#{quote_column_name "notice"} ILIKE #{quote "%Notice%"})", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
58
58
|
end
|
59
59
|
|
60
60
|
def test_not
|
@@ -75,7 +75,7 @@ class VisitorTest < SearchCop::TestCase
|
|
75
75
|
node = SearchCopGrammar::Attributes::Collection.new(SearchCop::QueryInfo.new(Product, Product.search_scopes[:search]), "title").matches("Query").optimize!
|
76
76
|
|
77
77
|
assert_equal("MATCH(`products`.`title`) AGAINST('Query' IN BOOLEAN MODE)", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "mysql"
|
78
|
-
assert_equal("to_tsvector('english', \"products\".\"title\") @@ to_tsquery('english', '''Query''')", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
78
|
+
assert_equal("to_tsvector('english', COALESCE(\"products\".\"title\", '')) @@ to_tsquery('english', '''Query''')", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
79
79
|
end
|
80
80
|
|
81
81
|
def test_fulltext_and
|
@@ -85,7 +85,7 @@ class VisitorTest < SearchCop::TestCase
|
|
85
85
|
node = query1.and(query2).optimize!
|
86
86
|
|
87
87
|
assert_equal("(MATCH(`products`.`title`) AGAINST('+Query1 +Query2' IN BOOLEAN MODE))", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "mysql"
|
88
|
-
assert_equal("(to_tsvector('english', \"products\".\"title\") @@ to_tsquery('english', '(''Query1'') & (''Query2'')'))", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
88
|
+
assert_equal("(to_tsvector('english', COALESCE(\"products\".\"title\", '')) @@ to_tsquery('english', '(''Query1'') & (''Query2'')'))", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
89
89
|
end
|
90
90
|
|
91
91
|
def test_fulltext_or
|
@@ -95,7 +95,7 @@ class VisitorTest < SearchCop::TestCase
|
|
95
95
|
node = query1.or(query2).optimize!
|
96
96
|
|
97
97
|
assert_equal("(MATCH(`products`.`title`) AGAINST('(Query1) (Query2)' IN BOOLEAN MODE))", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "mysql"
|
98
|
-
assert_equal("(to_tsvector('english', \"products\".\"title\") @@ to_tsquery('english', '(''Query1'') | (''Query2'')'))", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
98
|
+
assert_equal("(to_tsvector('english', COALESCE(\"products\".\"title\", '')) @@ to_tsquery('english', '(''Query1'') | (''Query2'')'))", SearchCop::Visitors::Visitor.new(ActiveRecord::Base.connection).visit(node)) if ENV["DATABASE"] == "postgres"
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
metadata
CHANGED
@@ -1,126 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_cop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.7
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Benjamin Vetter
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2017-02-22 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: treetop
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: bundler
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
33
|
+
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
40
|
+
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rake
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - ">="
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - ">="
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: activerecord
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - ">="
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: 3.0.0
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - ">="
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: 3.0.0
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: factory_girl
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - ">="
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - ">="
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: appraisal
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - ">="
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - ">="
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: minitest
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - ">="
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - ">="
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0'
|
126
111
|
description: Search engine like fulltext query support for ActiveRecord
|
@@ -130,10 +115,11 @@ executables: []
|
|
130
115
|
extensions: []
|
131
116
|
extra_rdoc_files: []
|
132
117
|
files:
|
133
|
-
- .gitignore
|
134
|
-
- .travis.yml
|
118
|
+
- ".gitignore"
|
119
|
+
- ".travis.yml"
|
135
120
|
- Appraisals
|
136
121
|
- CHANGELOG.md
|
122
|
+
- CONTRIBUTING.md
|
137
123
|
- Gemfile
|
138
124
|
- LICENSE.txt
|
139
125
|
- MIGRATION.md
|
@@ -143,6 +129,7 @@ files:
|
|
143
129
|
- gemfiles/4.0.gemfile
|
144
130
|
- gemfiles/4.1.gemfile
|
145
131
|
- gemfiles/4.2.gemfile
|
132
|
+
- gemfiles/5.0.gemfile
|
146
133
|
- lib/search_cop.rb
|
147
134
|
- lib/search_cop/grammar_parser.rb
|
148
135
|
- lib/search_cop/hash_parser.rb
|
@@ -179,27 +166,26 @@ files:
|
|
179
166
|
homepage: https://github.com/mrkamel/search_cop
|
180
167
|
licenses:
|
181
168
|
- MIT
|
169
|
+
metadata: {}
|
182
170
|
post_install_message:
|
183
171
|
rdoc_options: []
|
184
172
|
require_paths:
|
185
173
|
- lib
|
186
174
|
required_ruby_version: !ruby/object:Gem::Requirement
|
187
|
-
none: false
|
188
175
|
requirements:
|
189
|
-
- -
|
176
|
+
- - ">="
|
190
177
|
- !ruby/object:Gem::Version
|
191
178
|
version: '0'
|
192
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
|
-
none: false
|
194
180
|
requirements:
|
195
|
-
- -
|
181
|
+
- - ">="
|
196
182
|
- !ruby/object:Gem::Version
|
197
183
|
version: '0'
|
198
184
|
requirements: []
|
199
185
|
rubyforge_project:
|
200
|
-
rubygems_version:
|
186
|
+
rubygems_version: 2.2.2
|
201
187
|
signing_key:
|
202
|
-
specification_version:
|
188
|
+
specification_version: 4
|
203
189
|
summary: Easily perform complex search engine like fulltext queries on your ActiveRecord
|
204
190
|
models
|
205
191
|
test_files:
|