Commit 3df045a3d82f265378048693ada801e867bc680d

Authored by Andrew Kane
1 parent 0a17dd2e

Added experimental support for Cequel - #828

lib/searchkick.rb
@@ -169,6 +169,8 @@ module Searchkick @@ -169,6 +169,8 @@ module Searchkick
169 elsif records.respond_to?(:unscoped) && :id.respond_to?(:in) 169 elsif records.respond_to?(:unscoped) && :id.respond_to?(:in)
170 # Nobrainer 170 # Nobrainer
171 records.unscoped.where(:id.in => ids) 171 records.unscoped.where(:id.in => ids)
  172 + elsif records.respond_to?(:key_column_names)
  173 + records.where(records.key_column_names.first => ids)
172 end 174 end
173 175
174 raise Searchkick::Error, "Not sure how to load records" if !records 176 raise Searchkick::Error, "Not sure how to load records" if !records
lib/searchkick/model.rb
@@ -144,6 +144,12 @@ module Searchkick @@ -144,6 +144,12 @@ module Searchkick
144 def should_index? 144 def should_index?
145 true 145 true
146 end unless method_defined?(:should_index?) 146 end unless method_defined?(:should_index?)
  147 +
  148 + if defined?(Cequel) && self < Cequel::Record && !method_defined?(:destroyed?)
  149 + def destroyed?
  150 + transient?
  151 + end
  152 + end
147 end 153 end
148 end 154 end
149 end 155 end
lib/searchkick/reindex_v2_job.rb
@@ -3,7 +3,8 @@ module Searchkick @@ -3,7 +3,8 @@ module Searchkick
3 RECORD_NOT_FOUND_CLASSES = [ 3 RECORD_NOT_FOUND_CLASSES = [
4 "ActiveRecord::RecordNotFound", 4 "ActiveRecord::RecordNotFound",
5 "Mongoid::Errors::DocumentNotFound", 5 "Mongoid::Errors::DocumentNotFound",
6 - "NoBrainer::Error::DocumentNotFound" 6 + "NoBrainer::Error::DocumentNotFound",
  7 + "Cequel::Record::RecordNotFound"
7 ] 8 ]
8 9
9 queue_as :searchkick 10 queue_as :searchkick
test/aggs_test.rb
@@ -6,8 +6,8 @@ class AggsTest &lt; Minitest::Test @@ -6,8 +6,8 @@ class AggsTest &lt; Minitest::Test
6 store [ 6 store [
7 {name: "Product Show", latitude: 37.7833, longitude: 12.4167, store_id: 1, in_stock: true, color: "blue", price: 21, created_at: 2.days.ago}, 7 {name: "Product Show", latitude: 37.7833, longitude: 12.4167, store_id: 1, in_stock: true, color: "blue", price: 21, created_at: 2.days.ago},
8 {name: "Product Hide", latitude: 29.4167, longitude: -98.5000, store_id: 2, in_stock: false, color: "green", price: 25, created_at: 2.days.from_now}, 8 {name: "Product Hide", latitude: 29.4167, longitude: -98.5000, store_id: 2, in_stock: false, color: "green", price: 25, created_at: 2.days.from_now},
9 - {name: "Product B", latitude: 43.9333, longitude: -122.4667, store_id: 2, in_stock: false, color: "red", price: 5},  
10 - {name: "Foo", latitude: 43.9333, longitude: 12.4667, store_id: 3, in_stock: false, color: "yellow", price: 15} 9 + {name: "Product B", latitude: 43.9333, longitude: -122.4667, store_id: 2, in_stock: false, color: "red", price: 5, created_at: Time.now},
  10 + {name: "Foo", latitude: 43.9333, longitude: 12.4667, store_id: 3, in_stock: false, color: "yellow", price: 15, created_at: Time.now}
11 ] 11 ]
12 end 12 end
13 13
test/boost_test.rb
@@ -157,6 +157,8 @@ class BoostTest &lt; Minitest::Test @@ -157,6 +157,8 @@ class BoostTest &lt; Minitest::Test
157 end 157 end
158 158
159 def test_boost_by_indices 159 def test_boost_by_indices
  160 + skip if cequel?
  161 +
160 store_names ["Rex"], Animal 162 store_names ["Rex"], Animal
161 store_names ["Rexx"], Product 163 store_names ["Rexx"], Product
162 164
test/errors_test.rb
@@ -2,8 +2,8 @@ require_relative &quot;test_helper&quot; @@ -2,8 +2,8 @@ require_relative &quot;test_helper&quot;
2 2
3 class ErrorsTest < Minitest::Test 3 class ErrorsTest < Minitest::Test
4 def test_bulk_import_raises_error 4 def test_bulk_import_raises_error
5 - valid_dog = Dog.new(name: "2016-01-02")  
6 - invalid_dog = Dog.new(name: "Ol' One-Leg") 5 + valid_dog = Product.new(name: "2016-01-02")
  6 + invalid_dog = Product.new(name: "Ol' One-Leg")
7 index = Searchkick::Index.new "dogs", mappings: { 7 index = Searchkick::Index.new "dogs", mappings: {
8 dog: { 8 dog: {
9 properties: { 9 properties: {
test/gemfiles/cequel.gemfile 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +source 'https://rubygems.org'
  2 +
  3 +# Specify your gem's dependencies in searchkick.gemspec
  4 +gemspec path: "../../"
  5 +
  6 +gem "cequel"
  7 +gem "activejob"
  8 +gem "redis"
test/inheritance_test.rb
1 require_relative "test_helper" 1 require_relative "test_helper"
2 2
3 class InheritanceTest < Minitest::Test 3 class InheritanceTest < Minitest::Test
  4 + def setup
  5 + skip if defined?(Cequel)
  6 + super
  7 + end
  8 +
4 def test_child_reindex 9 def test_child_reindex
5 store_names ["Max"], Cat 10 store_names ["Max"], Cat
6 assert Dog.reindex 11 assert Dog.reindex
test/match_test.rb
@@ -184,6 +184,7 @@ class MatchTest &lt; Minitest::Test @@ -184,6 +184,7 @@ class MatchTest &lt; Minitest::Test
184 end 184 end
185 185
186 def test_no_arguments 186 def test_no_arguments
  187 + store_names []
187 assert_equal [], Product.search.to_a 188 assert_equal [], Product.search.to_a
188 end 189 end
189 190
test/model_test.rb
@@ -37,6 +37,6 @@ class ModelTest &lt; Minitest::Test @@ -37,6 +37,6 @@ class ModelTest &lt; Minitest::Test
37 def test_multiple_models 37 def test_multiple_models
38 store_names ["Product A"] 38 store_names ["Product A"]
39 store_names ["Product B"], Speaker 39 store_names ["Product B"], Speaker
40 - assert_equal Product.all + Speaker.all, Searchkick.search("product", index_name: [Product, Speaker], fields: [:name], order: "name").to_a 40 + assert_equal Product.all.to_a + Speaker.all.to_a, Searchkick.search("product", index_name: [Product, Speaker], fields: [:name], order: "name").to_a
41 end 41 end
42 end 42 end
test/order_test.rb
@@ -12,6 +12,8 @@ class OrderTest &lt; Minitest::Test @@ -12,6 +12,8 @@ class OrderTest &lt; Minitest::Test
12 end 12 end
13 13
14 def test_order_id 14 def test_order_id
  15 + skip if cequel?
  16 +
15 store_names ["Product A", "Product B"] 17 store_names ["Product A", "Product B"]
16 product_a = Product.where(name: "Product A").first 18 product_a = Product.where(name: "Product A").first
17 product_b = Product.where(name: "Product B").first 19 product_b = Product.where(name: "Product B").first
test/records_test.rb
@@ -2,6 +2,8 @@ require_relative &quot;test_helper&quot; @@ -2,6 +2,8 @@ require_relative &quot;test_helper&quot;
2 2
3 class RecordsTest < Minitest::Test 3 class RecordsTest < Minitest::Test
4 def test_records 4 def test_records
  5 + skip if cequel?
  6 +
5 store_names ["Milk", "Apple"] 7 store_names ["Milk", "Apple"]
6 assert_equal Product.search("milk").records.where(name: "Milk").count, 1 8 assert_equal Product.search("milk").records.where(name: "Milk").count, 1
7 end 9 end
test/reindex_test.rb
@@ -2,7 +2,7 @@ require_relative &quot;test_helper&quot; @@ -2,7 +2,7 @@ require_relative &quot;test_helper&quot;
2 2
3 class ReindexTest < Minitest::Test 3 class ReindexTest < Minitest::Test
4 def test_scoped 4 def test_scoped
5 - skip if nobrainer? 5 + skip if nobrainer? || cequel?
6 6
7 store_names ["Product A"] 7 store_names ["Product A"]
8 Searchkick.callbacks(false) do 8 Searchkick.callbacks(false) do
@@ -13,7 +13,7 @@ class ReindexTest &lt; Minitest::Test @@ -13,7 +13,7 @@ class ReindexTest &lt; Minitest::Test
13 end 13 end
14 14
15 def test_associations 15 def test_associations
16 - skip if nobrainer? 16 + skip if nobrainer? || cequel?
17 17
18 store_names ["Product A"] 18 store_names ["Product A"]
19 store = Store.create!(name: "Test") 19 store = Store.create!(name: "Test")
test/test_helper.rb
@@ -45,6 +45,10 @@ def nobrainer? @@ -45,6 +45,10 @@ def nobrainer?
45 defined?(NoBrainer) 45 defined?(NoBrainer)
46 end 46 end
47 47
  48 +def cequel?
  49 + defined?(Cequel)
  50 +end
  51 +
48 if defined?(Mongoid) 52 if defined?(Mongoid)
49 Mongoid.logger.level = Logger::INFO 53 Mongoid.logger.level = Logger::INFO
50 Mongo::Logger.logger.level = Logger::INFO if defined?(Mongo::Logger) 54 Mongo::Logger.logger.level = Logger::INFO if defined?(Mongo::Logger)
@@ -162,6 +166,87 @@ elsif defined?(NoBrainer) @@ -162,6 +166,87 @@ elsif defined?(NoBrainer)
162 166
163 class Cat < Animal 167 class Cat < Animal
164 end 168 end
  169 +elsif defined?(Cequel)
  170 + cequel =
  171 + Cequel.connect(
  172 + host: "127.0.0.1",
  173 + port: 9042,
  174 + keyspace: "searchkick_test",
  175 + default_consistency: :all
  176 + )
  177 + cequel.schema.drop! if cequel.schema.exists?
  178 + cequel.schema.create!
  179 + Cequel::Record.connection = cequel
  180 +
  181 + class Product
  182 + include Cequel::Record
  183 +
  184 + key :id, :uuid, auto: true
  185 + column :name, :text, index: true
  186 + column :store_id, :int
  187 + column :in_stock, :boolean
  188 + column :backordered, :boolean
  189 + column :orders_count, :int
  190 + column :found_rate, :decimal
  191 + column :price, :int
  192 + column :color, :text
  193 + column :latitude, :decimal
  194 + column :longitude, :decimal
  195 + column :description, :text
  196 + column :alt_description, :text
  197 + column :created_at, :timestamp
  198 + end
  199 +
  200 + class Store
  201 + include Cequel::Record
  202 +
  203 + key :id, :timeuuid, auto: true
  204 + column :name, :text
  205 +
  206 + # has issue with id serialization
  207 + def search_data
  208 + {
  209 + name: name
  210 + }
  211 + end
  212 + end
  213 +
  214 + class Region
  215 + include Cequel::Record
  216 +
  217 + key :id, :timeuuid, auto: true
  218 + column :name, :text
  219 + column :text, :text
  220 + end
  221 +
  222 + class Speaker
  223 + include Cequel::Record
  224 +
  225 + key :id, :timeuuid, auto: true
  226 + column :name, :text
  227 + end
  228 +
  229 + class Animal
  230 + include Cequel::Record
  231 +
  232 + key :id, :timeuuid, auto: true
  233 + column :name, :text
  234 +
  235 + # has issue with id serialization
  236 + def search_data
  237 + {
  238 + name: name
  239 + }
  240 + end
  241 + end
  242 +
  243 + class Dog < Animal
  244 + end
  245 +
  246 + class Cat < Animal
  247 + end
  248 +
  249 + [Product, Store, Region, Speaker, Animal].each(&:synchronize_schema)
165 else 250 else
166 require "active_record" 251 require "active_record"
167 252
test/where_test.rb
@@ -10,16 +10,22 @@ class WhereTest &lt; Minitest::Test @@ -10,16 +10,22 @@ class WhereTest &lt; Minitest::Test
10 {name: "Product D", store_id: 4, in_stock: false, backordered: false, created_at: now - 3, orders_count: 1} 10 {name: "Product D", store_id: 4, in_stock: false, backordered: false, created_at: now - 3, orders_count: 1}
11 ] 11 ]
12 assert_search "product", ["Product A", "Product B"], where: {in_stock: true} 12 assert_search "product", ["Product A", "Product B"], where: {in_stock: true}
13 - # date  
14 - assert_search "product", ["Product A"], where: {created_at: {gt: now - 1}}  
15 - assert_search "product", ["Product A", "Product B"], where: {created_at: {gte: now - 1}}  
16 - assert_search "product", ["Product D"], where: {created_at: {lt: now - 2}}  
17 - assert_search "product", ["Product C", "Product D"], where: {created_at: {lte: now - 2}} 13 +
  14 + # due to precision
  15 + unless cequel?
  16 + # date
  17 + assert_search "product", ["Product A"], where: {created_at: {gt: now - 1}}
  18 + assert_search "product", ["Product A", "Product B"], where: {created_at: {gte: now - 1}}
  19 + assert_search "product", ["Product D"], where: {created_at: {lt: now - 2}}
  20 + assert_search "product", ["Product C", "Product D"], where: {created_at: {lte: now - 2}}
  21 + end
  22 +
18 # integer 23 # integer
19 assert_search "product", ["Product A"], where: {store_id: {lt: 2}} 24 assert_search "product", ["Product A"], where: {store_id: {lt: 2}}
20 assert_search "product", ["Product A", "Product B"], where: {store_id: {lte: 2}} 25 assert_search "product", ["Product A", "Product B"], where: {store_id: {lte: 2}}
21 assert_search "product", ["Product D"], where: {store_id: {gt: 3}} 26 assert_search "product", ["Product D"], where: {store_id: {gt: 3}}
22 assert_search "product", ["Product C", "Product D"], where: {store_id: {gte: 3}} 27 assert_search "product", ["Product C", "Product D"], where: {store_id: {gte: 3}}
  28 +
23 # range 29 # range
24 assert_search "product", ["Product A", "Product B"], where: {store_id: 1..2} 30 assert_search "product", ["Product A", "Product B"], where: {store_id: 1..2}
25 assert_search "product", ["Product A"], where: {store_id: 1...2} 31 assert_search "product", ["Product A"], where: {store_id: 1...2}
@@ -27,23 +33,30 @@ class WhereTest &lt; Minitest::Test @@ -27,23 +33,30 @@ class WhereTest &lt; Minitest::Test
27 assert_search "product", ["Product B", "Product C", "Product D"], where: {store_id: {not: 1}} 33 assert_search "product", ["Product B", "Product C", "Product D"], where: {store_id: {not: 1}}
28 assert_search "product", ["Product C", "Product D"], where: {store_id: {not: [1, 2]}} 34 assert_search "product", ["Product C", "Product D"], where: {store_id: {not: [1, 2]}}
29 assert_search "product", ["Product A"], where: {user_ids: {lte: 2, gte: 2}} 35 assert_search "product", ["Product A"], where: {user_ids: {lte: 2, gte: 2}}
  36 +
30 # or 37 # or
31 assert_search "product", ["Product A", "Product B", "Product C"], where: {or: [[{in_stock: true}, {store_id: 3}]]} 38 assert_search "product", ["Product A", "Product B", "Product C"], where: {or: [[{in_stock: true}, {store_id: 3}]]}
32 assert_search "product", ["Product A", "Product B", "Product C"], where: {or: [[{orders_count: [2, 4]}, {store_id: [1, 2]}]]} 39 assert_search "product", ["Product A", "Product B", "Product C"], where: {or: [[{orders_count: [2, 4]}, {store_id: [1, 2]}]]}
33 assert_search "product", ["Product A", "Product D"], where: {or: [[{orders_count: 1}, {created_at: {gte: now - 1}, backordered: true}]]} 40 assert_search "product", ["Product A", "Product D"], where: {or: [[{orders_count: 1}, {created_at: {gte: now - 1}, backordered: true}]]}
  41 +
34 # _or 42 # _or
35 assert_search "product", ["Product A", "Product B", "Product C"], where: {_or: [{in_stock: true}, {store_id: 3}]} 43 assert_search "product", ["Product A", "Product B", "Product C"], where: {_or: [{in_stock: true}, {store_id: 3}]}
36 assert_search "product", ["Product A", "Product B", "Product C"], where: {_or: [{orders_count: [2, 4]}, {store_id: [1, 2]}]} 44 assert_search "product", ["Product A", "Product B", "Product C"], where: {_or: [{orders_count: [2, 4]}, {store_id: [1, 2]}]}
37 assert_search "product", ["Product A", "Product D"], where: {_or: [{orders_count: 1}, {created_at: {gte: now - 1}, backordered: true}]} 45 assert_search "product", ["Product A", "Product D"], where: {_or: [{orders_count: 1}, {created_at: {gte: now - 1}, backordered: true}]}
  46 +
38 # _and 47 # _and
39 assert_search "product", ["Product A"], where: {_and: [{in_stock: true}, {backordered: true}]} 48 assert_search "product", ["Product A"], where: {_and: [{in_stock: true}, {backordered: true}]}
  49 +
40 # _not 50 # _not
41 assert_search "product", ["Product B", "Product C"], where: {_not: {_or: [{orders_count: 1}, {created_at: {gte: now - 1}, backordered: true}]}} 51 assert_search "product", ["Product B", "Product C"], where: {_not: {_or: [{orders_count: 1}, {created_at: {gte: now - 1}, backordered: true}]}}
  52 +
42 # all 53 # all
43 assert_search "product", ["Product A", "Product C"], where: {user_ids: {all: [1, 3]}} 54 assert_search "product", ["Product A", "Product C"], where: {user_ids: {all: [1, 3]}}
44 assert_search "product", [], where: {user_ids: {all: [1, 2, 3, 4]}} 55 assert_search "product", [], where: {user_ids: {all: [1, 2, 3, 4]}}
  56 +
45 # any / nested terms 57 # any / nested terms
46 assert_search "product", ["Product B", "Product C"], where: {user_ids: {not: [2], in: [1, 3]}} 58 assert_search "product", ["Product B", "Product C"], where: {user_ids: {not: [2], in: [1, 3]}}
  59 +
47 # not / exists 60 # not / exists
48 assert_search "product", ["Product D"], where: {user_ids: nil} 61 assert_search "product", ["Product D"], where: {user_ids: nil}
49 assert_search "product", ["Product A", "Product B", "Product C"], where: {user_ids: {not: nil}} 62 assert_search "product", ["Product A", "Product B", "Product C"], where: {user_ids: {not: nil}}
@@ -78,7 +91,7 @@ class WhereTest &lt; Minitest::Test @@ -78,7 +91,7 @@ class WhereTest &lt; Minitest::Test
78 91
79 def test_where_id 92 def test_where_id
80 store_names ["Product A"] 93 store_names ["Product A"]
81 - product = Product.last 94 + product = Product.first
82 assert_search "product", ["Product A"], where: {id: product.id.to_s} 95 assert_search "product", ["Product A"], where: {id: product.id.to_s}
83 end 96 end
84 97