search_cop 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
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.9.3
11
- - 2.0.0
12
- - 2.1.1
13
- - rbx-2
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-2
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.18"
3
+ gem "activerecord", "~> 3.2"
3
4
  gem "search_cop", :path => "../"
4
5
  end
5
6
 
6
- appraise "4.0" do
7
- gem "activerecord", "~> 4.0.0"
7
+ appraise "4.1" do
8
+ gem "activerecord", "~> 4.1"
8
9
  gem "search_cop", :path => "../"
9
10
  end
10
11
 
11
- appraise "4.1" do
12
- gem "activerecord", "~> 4.1.0.beta"
12
+ appraise "4.2" do
13
+ gem "activerecord", "~> 4.2"
13
14
  gem "search_cop", :path => "../"
14
15
  end
15
16
 
16
- appraise "4.2" do
17
- gem "activerecord", "~> 4.2.0.beta"
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
@@ -1,6 +1,10 @@
1
1
 
2
2
  # Changelog
3
3
 
4
+ Version 1.0.6:
5
+
6
+ * Fixes a bug regarding date overflows in PostgreSQL
7
+
4
8
  Version 1.0.5:
5
9
 
6
10
  * Fixes a bug regarding quotation
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, :dictionary => "english"
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.18"
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.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.0.beta"
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.0.beta"
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 => "../"
@@ -1,3 +1,3 @@
1
1
  module SearchCop
2
- VERSION = "1.0.6"
2
+ VERSION = "1.0.7"
3
3
  end
@@ -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 |node|
18
- if node.is_a?(SearchCopGrammar::Nodes::MatchesFulltextNot)
19
- visit node
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
- node.nodes.size > 1 ? "+(#{visit node})" : "+#{visit node}"
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 { |node| "(#{visit node})" }.join(" ")
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 /[\s&|!:'"]+/, " "}'"
7
+ "!'#{node.right.gsub(/[\s&|!:'"]+/, " ")}'"
8
8
  end
9
9
 
10
10
  def visit_SearchCopGrammar_Nodes_MatchesFulltext(node)
11
- "'#{node.right.gsub /[\s&|!:'"]+/, " "}'"
11
+ "'#{node.right.gsub(/[\s&|!:'"]+/, " ")}'"
12
12
  end
13
13
 
14
14
  def visit_SearchCopGrammar_Nodes_And_Fulltext(node)
15
- node.nodes.collect { |node| "(#{visit node})" }.join(" & ")
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 { |node| "(#{visit node})" }.join(" | ")
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 { |attribute| visit attribute }.join(" || ' ' || ")
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 /::/, "_"}", visit_node
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
- else
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
- else
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}"
@@ -82,6 +82,12 @@ module SearchCopGrammar
82
82
  def initialize(object)
83
83
  @object = object
84
84
  end
85
+
86
+ def finalize!
87
+ @object.finalize!
88
+
89
+ self
90
+ end
85
91
  end
86
92
 
87
93
  class MatchesFulltext < Binary
@@ -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", "~> 1.3"
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"
@@ -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("title:word1 OR (title:word2 -title:word3)")
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("title:Expected title:Title stock > 0")
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.6
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: 2015-03-07 00:00:00.000000000 Z
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: '1.3'
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: '1.3'
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: 1.8.23
186
+ rubygems_version: 2.2.2
201
187
  signing_key:
202
- specification_version: 3
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: