sunspot_activerecord 0.0.2 → 0.0.3

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.
@@ -126,7 +126,7 @@ module SunspotActiveRecord #:nodoc:
126
126
  #
127
127
  # ==== Options
128
128
  #
129
- # :include:: Specify associations to eager load
129
+ # :include :: Specify associations to eager load
130
130
  # :select:: Specify columns to select from database when loading results
131
131
  #
132
132
  # ==== Returns
@@ -231,9 +231,9 @@ module SunspotActiveRecord #:nodoc:
231
231
  if options[:batch_size]
232
232
  counter = 0
233
233
  find_in_batches(:include => options[:include], :batch_size => options[:batch_size]) do |records|
234
- solr_benchmark options[:batch_size], counter do
234
+ #solr_benchmark options[:batch_size], counter do
235
235
  Sunspot.index(records)
236
- end
236
+ #end
237
237
  Sunspot.commit if options[:batch_commit]
238
238
  counter += 1
239
239
  end
@@ -316,10 +316,10 @@ module SunspotActiveRecord #:nodoc:
316
316
  #
317
317
  def solr_benchmark(batch_size, counter, &block)
318
318
  start = Time.now
319
- logger.info("[#{Time.now}] Start Indexing")
319
+ #logger.info("[#{Time.now}] Start Indexing")
320
320
  yield
321
321
  elapsed = Time.now-start
322
- logger.info("[#{Time.now}] Completed Indexing. Rows indexed #{counter * batch_size}. Rows/sec: #{batch_size/elapsed.to_f} (Elapsed: #{elapsed} sec.)")
322
+ #logger.info("[#{Time.now}] Completed Indexing. Rows indexed #{counter * batch_size}. Rows/sec: #{batch_size/elapsed.to_f} (Elapsed: #{elapsed} sec.)")
323
323
  end
324
324
 
325
325
  end
@@ -1,3 +1,3 @@
1
1
  module SunspotActiverecord
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/spec/app/boot.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+ require 'sunspot'
4
+ require 'sunspot_activerecord'
5
+
6
+ ENV['APP_ROOT'] ||= File.dirname(__FILE__)
7
+ env = ENV['APP_ENV'] || 'development'
8
+
9
+ db = YAML.load_file(File.join(ENV['APP_ROOT'], 'db', 'database.yml'))
10
+ db[env][:database] = ENV['APP_ROOT'] + '/' + db[env][:database]
11
+ ActiveRecord::Base.establish_connection(db[env])
12
+
13
+
14
+ $LOAD_PATH.unshift("#{ENV['APP_ROOT']}/models")
15
+ Dir.glob("#{ENV['APP_ROOT']}/models/*.rb") { |model| require File.basename(model, '.*') }
@@ -0,0 +1,5 @@
1
+ test: &test
2
+ :adapter: sqlite3
3
+ :database: db/test.sqlite3
4
+
5
+ development: *test
@@ -0,0 +1,27 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :posts, :force => true do |t|
3
+ t.string :title
4
+ t.string :type
5
+ t.integer :location_id
6
+ t.text :body
7
+ t.references :blog
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :locations, :force => true do |t|
12
+ t.float :lat
13
+ t.float :lng
14
+ end
15
+
16
+ create_table :blogs, :force => true do |t|
17
+ t.string :name
18
+ t.string :subdomain
19
+ t.timestamps
20
+ end
21
+
22
+ create_table :writers, :force => true, :primary_key => :writer_id do |t|
23
+ t.string :name
24
+ t.timestamps
25
+ end
26
+
27
+ end
Binary file
@@ -0,0 +1,8 @@
1
+ class Author < ActiveRecord::Base
2
+ set_table_name :writers
3
+ set_primary_key :writer_id
4
+
5
+ searchable do
6
+ string :name
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ class Blog < ActiveRecord::Base
2
+ has_many :posts
3
+ has_many :comments, :through => :posts
4
+
5
+ searchable :include => { :posts => :author } do
6
+ string :subdomain
7
+ text :name
8
+ end
9
+
10
+ # Make sure that includes are added to with multiple searchable calls
11
+ searchable(:include => :comments) {}
12
+ end
@@ -0,0 +1,2 @@
1
+ class Location < ActiveRecord::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ class PhotoPost < PostWithAuto
2
+ end
@@ -0,0 +1,11 @@
1
+ class Post < ActiveRecord::Base
2
+ belongs_to :location
3
+ belongs_to :author
4
+ has_many :comments
5
+
6
+ searchable :auto_index => false, :auto_remove => false do
7
+ string :title
8
+ text :body, :more_like_this => true
9
+ location :location
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ class PostWithAuto < ActiveRecord::Base
2
+ def self.table_name
3
+ 'posts'
4
+ end
5
+
6
+ searchable :ignore_attribute_changes_of => [ :updated_at ] do
7
+ string :title
8
+ text :body, :more_like_this => true
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ class PostWithDefaultScope < ActiveRecord::Base
2
+ def self.table_name
3
+ 'posts'
4
+ end
5
+
6
+ default_scope :order => :title
7
+
8
+ searchable :auto_index => false, :auto_remove => false do
9
+ string :title
10
+ end
11
+ end
@@ -0,0 +1,357 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'ActiveRecord mixin' do
4
+ describe 'index()' do
5
+ before :each do
6
+ @post = Post.create!
7
+ #@post = Post.create!(:title => 'title', :body => 'body')
8
+ @post.index
9
+ end
10
+
11
+ it 'should not commit the model' do
12
+ Post.search.results.should be_empty
13
+ end
14
+
15
+ it 'should index the model' do
16
+ Sunspot.commit
17
+ Post.search.results.should == [@post]
18
+ end
19
+
20
+ it "should not blow up if there's a default scope specifying order" do
21
+ posts = Array.new(2) { |j| PostWithDefaultScope.create! :title => (10-j).to_s }
22
+ lambda { PostWithDefaultScope.index(:batch_size => 1) }.should_not raise_error
23
+ end
24
+ end
25
+
26
+ describe 'single table inheritence' do
27
+ before :each do
28
+ @post = PhotoPost.create!
29
+ end
30
+
31
+ it 'should not break auto-indexing' do
32
+ @post.title = 'Title'
33
+ lambda { @post.save! }.should_not raise_error
34
+ end
35
+ end
36
+
37
+ describe 'index!()' do
38
+ before :each do
39
+ @post = Post.create!
40
+ @post.index!
41
+ end
42
+
43
+ it 'should immediately index and commit' do
44
+ Post.search.results.should == [@post]
45
+ end
46
+ end
47
+
48
+ describe 'remove_from_index()' do
49
+ before :each do
50
+ @post = Post.create!
51
+ @post.index!
52
+ @post.remove_from_index
53
+ end
54
+
55
+ it 'should not commit immediately' do
56
+ Post.search.results.should == [@post]
57
+ end
58
+
59
+ it 'should remove the model from the index' do
60
+ Sunspot.commit
61
+ Post.search.results.should be_empty
62
+ end
63
+ end
64
+
65
+ describe 'remove_from_index!()' do
66
+ before :each do
67
+ @post = Post.create!
68
+ @post.index!
69
+ @post.remove_from_index!
70
+ end
71
+
72
+ it 'should immediately remove the model and commit' do
73
+ Post.search.results.should be_empty
74
+ end
75
+ end
76
+
77
+ describe 'remove_all_from_index' do
78
+ before :each do
79
+ @posts = Array.new(2) { Post.create! }.each { |post| Sunspot.index(post) }
80
+ Sunspot.commit
81
+ Post.remove_all_from_index
82
+ end
83
+
84
+ it 'should not commit immediately' do
85
+ Post.search.results.to_set.should == @posts.to_set
86
+ end
87
+
88
+ it 'should remove all instances from the index' do
89
+ Sunspot.commit
90
+ Post.search.results.should be_empty
91
+ end
92
+ end
93
+
94
+ describe 'remove_all_from_index!' do
95
+ before :each do
96
+ Array.new(2) { Post.create! }.each { |post| Sunspot.index(post) }
97
+ Sunspot.commit
98
+ Post.remove_all_from_index!
99
+ end
100
+
101
+ it 'should remove all instances from the index and commit immediately' do
102
+ Post.search.results.should be_empty
103
+ end
104
+ end
105
+
106
+ describe 'search()' do
107
+ before :each do
108
+ @post = Post.create!(:title => 'Test Post')
109
+ @post.index!
110
+ end
111
+
112
+ it 'should return results specified by search' do
113
+ Post.search do
114
+ with :title, 'Test Post'
115
+ end.results.should == [@post]
116
+ end
117
+
118
+ it 'should not return results excluded by search' do
119
+ Post.search do
120
+ with :title, 'Bogus Post'
121
+ end.results.should be_empty
122
+ end
123
+
124
+ it 'should use the include option on the data accessor when specified' do
125
+ Post.should_receive(:all).with(hash_including(:include => [:blog])).and_return([@post])
126
+ Post.search do
127
+ with :title, 'Test Post'
128
+ data_accessor_for(Post).include = [:blog]
129
+ end.results.should == [@post]
130
+ end
131
+
132
+ it 'should pass :include option from search call to data accessor' do
133
+ Post.should_receive(:all).with(hash_including(:include => [:blog])).and_return([@post])
134
+ Post.search(:include => [:blog]) do
135
+ with :title, 'Test Post'
136
+ end.results.should == [@post]
137
+ end
138
+
139
+ it 'should use the select option from search call to data accessor' do
140
+ Post.should_receive(:all).with(hash_including(:select => 'title, published_at')).and_return([@post])
141
+ Post.search(:select => 'title, published_at') do
142
+ with :title, 'Test Post'
143
+ end.results.should == [@post]
144
+ end
145
+
146
+ it 'should not allow bogus options to search' do
147
+ lambda { Post.search(:bogus => :option) }.should raise_error(ArgumentError)
148
+ end
149
+
150
+ it 'should use the select option on the data accessor when specified' do
151
+ Post.should_receive(:all).with(hash_including(:select => 'title, published_at')).and_return([@post])
152
+ Post.search do
153
+ with :title, 'Test Post'
154
+ data_accessor_for(Post).select = [:title, :published_at]
155
+ end.results.should == [@post]
156
+ end
157
+
158
+ it 'should not use the select option on the data accessor when not specified' do
159
+ Post.should_receive(:all).with(hash_not_including(:select)).and_return([@post])
160
+ Post.search do
161
+ with :title, 'Test Post'
162
+ end.results.should == [@post]
163
+ end
164
+
165
+ it 'should gracefully handle nonexistent records' do
166
+ post2 = Post.create!(:title => 'Test Post')
167
+ post2.index!
168
+ post2.destroy
169
+ Post.search do
170
+ with :title, 'Test Post'
171
+ end.results.should == [@post]
172
+ end
173
+
174
+ it 'should use an ActiveRecord object for coordinates' do
175
+ post = Post.new(:title => 'Test Post')
176
+ post.location = Location.create!(:lat => 40.0, :lng => -70.0)
177
+ post.save
178
+ post.index!
179
+ Post.search { with(:location).near(40.0, -70.0) }.results.should == [post]
180
+ end
181
+
182
+ end
183
+
184
+ describe 'search_ids()' do
185
+ before :each do
186
+ @posts = Array.new(2) { Post.create! }.each { |post| post.index }
187
+ Sunspot.commit
188
+ end
189
+
190
+ it 'should return IDs' do
191
+ Post.search_ids.to_set.should == @posts.map { |post| post.id }.to_set
192
+ end
193
+ end
194
+
195
+ describe 'searchable?()' do
196
+ it 'should not be true for models that have not been configured for search' do
197
+ Location.should_not be_searchable
198
+ end
199
+
200
+ it 'should be true for models that have been configured for search' do
201
+ Post.should be_searchable
202
+ end
203
+ end
204
+
205
+ describe 'index_orphans()' do
206
+ before :each do
207
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
208
+ Sunspot.commit
209
+ @posts.first.destroy
210
+ end
211
+
212
+ it 'should return IDs of objects that are in the index but not the database' do
213
+ Post.index_orphans.should == [@posts.first.id]
214
+ end
215
+ end
216
+
217
+ describe 'clean_index_orphans()' do
218
+ before :each do
219
+ @posts = Array.new(2) { Post.create }.each { |post| post.index }
220
+ Sunspot.commit
221
+ @posts.first.destroy
222
+ end
223
+
224
+ it 'should remove orphans from the index' do
225
+ Post.clean_index_orphans
226
+ Sunspot.commit
227
+ Post.search.results.should == [@posts.last]
228
+ end
229
+ end
230
+
231
+ describe 'reindex()' do
232
+ before :each do
233
+ @posts = Array.new(2) { Post.create }
234
+ end
235
+
236
+ it 'should index all instances' do
237
+ Post.reindex(:batch_size => nil)
238
+ Sunspot.commit
239
+ Post.search.results.to_set.should == @posts.to_set
240
+ end
241
+
242
+ it 'should remove all currently indexed instances' do
243
+ old_post = Post.create!
244
+ old_post.index!
245
+ old_post.destroy
246
+ Post.reindex
247
+ Sunspot.commit
248
+ Post.search.results.to_set.should == @posts.to_set
249
+ end
250
+
251
+ end
252
+
253
+ describe 'reindex() with real data' do
254
+ before :each do
255
+ @posts = Array.new(2) { Post.create }
256
+ end
257
+
258
+ it 'should index all instances' do
259
+ Post.reindex(:batch_size => nil)
260
+ Sunspot.commit
261
+ Post.search.results.to_set.should == @posts.to_set
262
+ end
263
+
264
+ it 'should remove all currently indexed instances' do
265
+ old_post = Post.create!
266
+ old_post.index!
267
+ old_post.destroy
268
+ Post.reindex
269
+ Sunspot.commit
270
+ Post.search.results.to_set.should == @posts.to_set
271
+ end
272
+
273
+ describe "using batch sizes" do
274
+ it 'should index with a specified batch size' do
275
+ Post.reindex(:batch_size => 1)
276
+ Sunspot.commit
277
+ Post.search.results.to_set.should == @posts.to_set
278
+ end
279
+ end
280
+ end
281
+
282
+
283
+
284
+ describe "reindex()" do
285
+
286
+ before(:each) do
287
+ @posts = Array.new(2) { Post.create }
288
+ end
289
+
290
+ describe "when not using batches" do
291
+
292
+ it "should select all if the batch_size is nil" do
293
+ Post.should_receive(:all).with(:include => []).and_return([])
294
+ Post.reindex(:batch_size => nil)
295
+ end
296
+
297
+ it "should search for models with includes" do
298
+ Post.should_receive(:all).with(:include => :author).and_return([])
299
+ Post.reindex(:batch_size => nil, :include => :author)
300
+ end
301
+
302
+ end
303
+
304
+ describe "when using batches" do
305
+ it "should commit after indexing each batch" do
306
+ Sunspot.should_receive(:commit).twice
307
+ Post.reindex(:batch_size => 1)
308
+ end
309
+
310
+ it "should commit after indexing everything" do
311
+ Sunspot.should_receive(:commit).once
312
+ Post.reindex(:batch_commit => false)
313
+ end
314
+ end
315
+ end
316
+
317
+ describe "more_like_this()" do
318
+ before(:each) do
319
+ @posts = [
320
+ Post.create!(:title => 'Post123', :body => "one two three"),
321
+ Post.create!(:title => 'Post345', :body => "three four five"),
322
+ Post.create!(:title => 'Post456', :body => "four five six"),
323
+ Post.create!(:title => 'Post234', :body => "two three four"),
324
+ ]
325
+ @posts_with_auto = [
326
+ PostWithAuto.create!(:body => "one two three"),
327
+ PostWithAuto.create!(:body => "four five six")
328
+ ]
329
+ @posts.each { |p| p.index! }
330
+ end
331
+
332
+ it "should return results" do
333
+ @posts.first.more_like_this.results.should == [@posts[3], @posts[1]]
334
+ end
335
+
336
+ it "should return results for specified classes" do
337
+ @posts.first.more_like_this(Post, PostWithAuto).results.to_set.should ==
338
+ Set[@posts_with_auto[0], @posts[1], @posts[3]]
339
+ end
340
+ end
341
+
342
+ describe 'more_like_this_ids()' do
343
+ before :each do
344
+ @posts = [
345
+ Post.create!(:title => 'Post123', :body => "one two three"),
346
+ Post.create!(:title => 'Post345', :body => "three four five"),
347
+ Post.create!(:title => 'Post456', :body => "four five six"),
348
+ Post.create!(:title => 'Post234', :body => "two three four"),
349
+ ]
350
+ @posts.each { |p| p.index! }
351
+ end
352
+
353
+ it 'should return IDs' do
354
+ @posts.first.more_like_this_ids.to_set.should == [@posts[3], @posts[1]].map { |post| post.id }.to_set
355
+ end
356
+ end
357
+ end
@@ -0,0 +1,57 @@
1
+ ENV['APP_ROOT'] ||= File.join(File.dirname(__FILE__), 'app')
2
+ ENV['APP_ENV'] ||= 'test'
3
+
4
+ if rsolr_version = ENV['RSOLR_GEM_VERSION']
5
+ STDERR.puts("Forcing RSolr version #{rsolr_version}")
6
+ gem "rsolr", rsolr_version
7
+ end
8
+
9
+ begin
10
+ require 'rspec'
11
+ # require 'rspec/rails'
12
+ rescue LoadError => e
13
+ require 'spec'
14
+ # require 'spec/rails'
15
+ end
16
+ require 'rake'
17
+ require 'rubygems'
18
+ require 'sqlite3'
19
+
20
+ #`sunspot-solr start`
21
+ require File.join(ENV['APP_ROOT'], 'boot.rb')
22
+ #require File.join('sunspot', 'rails', 'solr_logging')
23
+
24
+ def load_db
25
+ # stdout = $stdout
26
+ # $stdout = StringIO.new # suppress output while building the schema
27
+ # db = YAML.load_file(File.join(ENV['APP_ROOT'], 'db', 'database.yml'))
28
+ # ActiveRecord::Base.establish_connection(db['test'])
29
+
30
+ #load File.join(ENV['APP_ROOT'], 'schema.rb')
31
+ # $stdout = stdout
32
+ end
33
+
34
+ def silence_stderr(&block)
35
+ stderr = $stderr
36
+ $stderr = StringIO.new
37
+ yield
38
+ $stderr = stderr
39
+ end
40
+
41
+ rspec =
42
+ begin
43
+ RSpec
44
+ rescue NameError, ArgumentError
45
+ Spec::Runner
46
+ end
47
+
48
+ rspec.configure do |config|
49
+ config.before(:each) do
50
+ load_db
51
+ Sunspot.remove_all!
52
+ Location.delete_all
53
+ Author.delete_all
54
+ Blog.delete_all
55
+ Post.delete_all
56
+ end
57
+ end
@@ -20,4 +20,5 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
  s.add_dependency 'sunspot'
22
22
  s.add_dependency 'activerecord', "~> 2.3.8"
23
+ s.add_development_dependency 'rspec', '~> 1.2'
23
24
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sunspot_activerecord
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Olga Gorun
@@ -48,6 +48,21 @@ dependencies:
48
48
  version: 2.3.8
49
49
  type: :runtime
50
50
  version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rspec
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ hash: 11
60
+ segments:
61
+ - 1
62
+ - 2
63
+ version: "1.2"
64
+ type: :development
65
+ version_requirements: *id003
51
66
  description: Simplified version of sunspot_rails gem to enable usage of sunspot+active_record -based models in not Rails projects
52
67
  email:
53
68
  - ogorun@gmail.com
@@ -66,6 +81,19 @@ files:
66
81
  - lib/sunspot_activerecord/adapters.rb
67
82
  - lib/sunspot_activerecord/searchable.rb
68
83
  - lib/sunspot_activerecord/version.rb
84
+ - spec/app/boot.rb
85
+ - spec/app/db/database.yml
86
+ - spec/app/db/schema.rb
87
+ - spec/app/db/test.sqlite3
88
+ - spec/app/models/author.rb
89
+ - spec/app/models/blog.rb
90
+ - spec/app/models/location.rb
91
+ - spec/app/models/photo_post.rb
92
+ - spec/app/models/post.rb
93
+ - spec/app/models/post_with_auto.rb
94
+ - spec/app/models/post_with_default_scope.rb
95
+ - spec/model_spec.rb
96
+ - spec/spec_helper.rb
69
97
  - sunspot_activerecord.gemspec
70
98
  has_rdoc: true
71
99
  homepage: ""