erichummel-sunspot_rails 1.2.1a

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.
Files changed (45) hide show
  1. data/History.txt +51 -0
  2. data/LICENSE +18 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +258 -0
  5. data/Rakefile +18 -0
  6. data/TESTING.md +35 -0
  7. data/TODO +8 -0
  8. data/VERSION.yml +4 -0
  9. data/dev_tasks/rdoc.rake +24 -0
  10. data/dev_tasks/release.rake +4 -0
  11. data/dev_tasks/spec.rake +22 -0
  12. data/dev_tasks/todo.rake +4 -0
  13. data/generators/sunspot/sunspot_generator.rb +9 -0
  14. data/generators/sunspot/templates/sunspot.yml +18 -0
  15. data/install.rb +1 -0
  16. data/lib/generators/sunspot_rails/install/install_generator.rb +13 -0
  17. data/lib/generators/sunspot_rails/install/templates/config/sunspot.yml +17 -0
  18. data/lib/generators/sunspot_rails.rb +9 -0
  19. data/lib/sunspot/rails/adapters.rb +83 -0
  20. data/lib/sunspot/rails/configuration.rb +323 -0
  21. data/lib/sunspot/rails/init.rb +5 -0
  22. data/lib/sunspot/rails/log_subscriber.rb +33 -0
  23. data/lib/sunspot/rails/railtie.rb +36 -0
  24. data/lib/sunspot/rails/railties/controller_runtime.rb +36 -0
  25. data/lib/sunspot/rails/request_lifecycle.rb +36 -0
  26. data/lib/sunspot/rails/searchable.rb +412 -0
  27. data/lib/sunspot/rails/server.rb +173 -0
  28. data/lib/sunspot/rails/solr_instrumentation.rb +21 -0
  29. data/lib/sunspot/rails/solr_logging.rb +63 -0
  30. data/lib/sunspot/rails/spec_helper.rb +26 -0
  31. data/lib/sunspot/rails/stub_session_proxy.rb +88 -0
  32. data/lib/sunspot/rails/tasks.rb +62 -0
  33. data/lib/sunspot/rails/version.rb +5 -0
  34. data/lib/sunspot/rails.rb +59 -0
  35. data/lib/sunspot_rails.rb +12 -0
  36. data/spec/configuration_spec.rb +173 -0
  37. data/spec/model_lifecycle_spec.rb +63 -0
  38. data/spec/model_spec.rb +356 -0
  39. data/spec/request_lifecycle_spec.rb +61 -0
  40. data/spec/schema.rb +27 -0
  41. data/spec/server_spec.rb +37 -0
  42. data/spec/session_spec.rb +24 -0
  43. data/spec/spec_helper.rb +46 -0
  44. data/spec/stub_session_proxy_spec.rb +122 -0
  45. metadata +155 -0
@@ -0,0 +1,88 @@
1
+ module Sunspot
2
+ module Rails
3
+ class StubSessionProxy
4
+ attr_reader :original_session
5
+
6
+ def initialize(original_session)
7
+ @original_session = original_session
8
+ end
9
+
10
+ def index(*objects)
11
+ end
12
+
13
+ def index!(*objects)
14
+ end
15
+
16
+ def remove(*objects)
17
+ end
18
+
19
+ def remove!(*objects)
20
+ end
21
+
22
+ def remove_by_id(clazz, id)
23
+ end
24
+
25
+ def remove_by_id!(clazz, id)
26
+ end
27
+
28
+ def remove_all(clazz = nil)
29
+ end
30
+
31
+ def remove_all!(clazz = nil)
32
+ end
33
+
34
+ def dirty?
35
+ false
36
+ end
37
+
38
+ def delete_dirty?
39
+ false
40
+ end
41
+
42
+ def commit_if_dirty
43
+ end
44
+
45
+ def commit_if_delete_dirty
46
+ end
47
+
48
+ def commit
49
+ end
50
+
51
+ def search(*types)
52
+ Search.new
53
+ end
54
+
55
+ def new_search(*types)
56
+ Search.new
57
+ end
58
+
59
+ class Search
60
+ def build
61
+ self
62
+ end
63
+
64
+ def results
65
+ []
66
+ end
67
+
68
+ def hits(options = {})
69
+ []
70
+ end
71
+
72
+ def total
73
+ 0
74
+ end
75
+
76
+ def facet(name)
77
+ end
78
+
79
+ def dynamic_facet(name)
80
+ end
81
+
82
+ def execute
83
+ self
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,62 @@
1
+ namespace :sunspot do
2
+ namespace :solr do
3
+ desc 'Start the Solr instance'
4
+ task :start => :environment do
5
+ if RUBY_PLATFORM =~ /w(in)?32$/
6
+ abort('This command does not work on Windows. Please use rake sunspot:solr:run to run Solr in the foreground.')
7
+ end
8
+ Sunspot::Rails::Server.new.start
9
+ end
10
+
11
+ desc 'Run the Solr instance in the foreground'
12
+ task :run => :environment do
13
+ Sunspot::Rails::Server.new.run
14
+ end
15
+
16
+ desc 'Stop the Solr instance'
17
+ task :stop => :environment do
18
+ if RUBY_PLATFORM =~ /w(in)?32$/
19
+ abort('This command does not work on Windows.')
20
+ end
21
+ Sunspot::Rails::Server.new.stop
22
+ end
23
+
24
+ task :reindex => :"sunspot:reindex"
25
+ end
26
+
27
+ desc "Reindex all solr models that are located in your application's models directory."
28
+ # This task depends on the standard Rails file naming \
29
+ # conventions, in that the file name matches the defined class name. \
30
+ # By default the indexing system works in batches of 50 records, you can \
31
+ # set your own value for this by using the batch_size argument. You can \
32
+ # also optionally define a list of models to separated by a forward slash '/'
33
+ #
34
+ # $ rake sunspot:reindex # reindex all models
35
+ # $ rake sunspot:reindex[1000] # reindex in batches of 1000
36
+ # $ rake sunspot:reindex[false] # reindex without batching
37
+ # $ rake sunspot:reindex[,Post] # reindex only the Post model
38
+ # $ rake sunspot:reindex[1000,Post] # reindex only the Post model in
39
+ # # batchs of 1000
40
+ # $ rake sunspot:reindex[,Post+Author] # reindex Post and Author model
41
+ task :reindex, [:batch_size, :models] => [:environment] do |t, args|
42
+ reindex_options = {:batch_commit => false}
43
+ case args[:batch_size]
44
+ when 'false'
45
+ reindex_options[:batch_size] = nil
46
+ when /^\d+$/
47
+ reindex_options[:batch_size] = args[:batch_size].to_i if args[:batch_size].to_i > 0
48
+ end
49
+ unless args[:models]
50
+ models_path = Rails.root.join('app', 'models')
51
+ all_files = Dir.glob(models_path.join('**', '*.rb'))
52
+ all_models = all_files.map { |path| path.sub(models_path.to_s, '')[0..-4].camelize.sub(/^::/, '').constantize rescue nil }.compact
53
+ sunspot_models = all_models.select { |m| m < ActiveRecord::Base and m.searchable? }
54
+ else
55
+ sunspot_models = args[:models].split('+').map{|m| m.constantize}
56
+ end
57
+ sunspot_models.each do |model|
58
+ model.solr_reindex reindex_options
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,5 @@
1
+ module Sunspot
2
+ module Rails
3
+ VERSION = '1.2.1'
4
+ end
5
+ end
@@ -0,0 +1,59 @@
1
+ require 'sunspot'
2
+ require File.join(File.dirname(__FILE__), 'rails', 'configuration')
3
+ require File.join(File.dirname(__FILE__), 'rails', 'adapters')
4
+ require File.join(File.dirname(__FILE__), 'rails', 'request_lifecycle')
5
+ require File.join(File.dirname(__FILE__), 'rails', 'searchable')
6
+
7
+ module Sunspot #:nodoc:
8
+ module Rails #:nodoc:
9
+ autoload :SolrInstrumentation, File.join(File.dirname(__FILE__), 'rails', 'solr_instrumentation')
10
+ autoload :StubSessionProxy, File.join(File.dirname(__FILE__), 'rails', 'stub_session_proxy')
11
+ autoload :Server, File.join(File.dirname(__FILE__), 'rails', 'server')
12
+ autoload :VERSION, File.join(File.dirname(__FILE__), 'rails', 'version')
13
+
14
+ class <<self
15
+ attr_writer :configuration
16
+
17
+ def configuration
18
+ @configuration ||= Sunspot::Rails::Configuration.new
19
+ end
20
+
21
+ def reset
22
+ @configuration = nil
23
+ end
24
+
25
+ def build_session(configuration = self.configuration)
26
+ if configuration.has_master?
27
+ SessionProxy::MasterSlaveSessionProxy.new(
28
+ SessionProxy::ThreadLocalSessionProxy.new(master_config(configuration)),
29
+ SessionProxy::ThreadLocalSessionProxy.new(slave_config(configuration))
30
+ )
31
+ else
32
+ SessionProxy::ThreadLocalSessionProxy.new(slave_config(configuration))
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def master_config(sunspot_rails_configuration)
39
+ config = Sunspot::Configuration.build
40
+ config.solr.url = URI::HTTP.build(
41
+ :host => sunspot_rails_configuration.master_hostname,
42
+ :port => sunspot_rails_configuration.master_port,
43
+ :path => sunspot_rails_configuration.master_path
44
+ ).to_s
45
+ config
46
+ end
47
+
48
+ def slave_config(sunspot_rails_configuration)
49
+ config = Sunspot::Configuration.build
50
+ config.solr.url = URI::HTTP.build(
51
+ :host => sunspot_rails_configuration.hostname,
52
+ :port => sunspot_rails_configuration.port,
53
+ :path => sunspot_rails_configuration.path
54
+ ).to_s
55
+ config
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ # This needs to be loaded before sunspot/search/paginated_collection
2
+ # or #to_json gets defined in Object breaking delegation to Array via
3
+ # method_missing
4
+ require 'active_support/core_ext/object/to_json' if Rails::VERSION::MAJOR == 3
5
+
6
+ require 'sunspot/rails'
7
+
8
+ if Rails::VERSION::MAJOR == 3
9
+ require 'sunspot/rails/railtie'
10
+ else
11
+ require 'sunspot/rails/init'
12
+ end
@@ -0,0 +1,173 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Sunspot::Rails::Configuration, "default values without a sunspot.yml" do
4
+ before(:each) do
5
+ File.stub!(:exist?).and_return(false) # simulate sunspot.yml not existing
6
+ @config = Sunspot::Rails::Configuration.new
7
+ end
8
+
9
+ it "should handle the 'hostname' property when not set" do
10
+ @config.hostname.should == 'localhost'
11
+ end
12
+
13
+ it "should handle the 'path' property when not set" do
14
+ @config.path.should == '/solr'
15
+ end
16
+
17
+ describe "port" do
18
+ it "should default to port 8981 in test" do
19
+ ::Rails.stub!(:env => 'test')
20
+ @config = Sunspot::Rails::Configuration.new
21
+ @config.port.should == 8981
22
+ end
23
+ it "should default to port 8982 in development" do
24
+ ::Rails.stub!(:env => 'development')
25
+ @config = Sunspot::Rails::Configuration.new
26
+ @config.port.should == 8982
27
+ end
28
+ it "should default to 8983 in production" do
29
+ ::Rails.stub!(:env => 'production')
30
+ @config = Sunspot::Rails::Configuration.new
31
+ @config.port.should == 8983
32
+ end
33
+ it "should generally default to 8983" do
34
+ ::Rails.stub!(:env => 'staging')
35
+ @config = Sunspot::Rails::Configuration.new
36
+ @config.port.should == 8983
37
+ end
38
+ end
39
+
40
+ it "should handle the 'log_level' property when not set" do
41
+ @config.log_level.should == 'INFO'
42
+ end
43
+
44
+ it "should handle the 'log_file' property" do
45
+ @config.log_file.should =~ /log\/solr_test.log/
46
+ end
47
+
48
+ it "should handle the 'solr_home' property when not set" do
49
+ Rails.should_receive(:root).at_least(1).and_return('/some/path')
50
+ @config.solr_home.should == '/some/path/solr'
51
+ end
52
+
53
+ it "should handle the 'data_path' property when not set" do
54
+ Rails.should_receive(:root).at_least(1).and_return('/some/path')
55
+ @config.data_path.should == '/some/path/solr/data/test'
56
+ end
57
+
58
+ it "should handle the 'pid_dir' property when not set" do
59
+ Rails.should_receive(:root).at_least(1).and_return('/some/path')
60
+ @config.pid_dir.should == '/some/path/solr/pids/test'
61
+ end
62
+
63
+ it "should handle the 'auto_commit_after_request' propery when not set" do
64
+ @config.auto_commit_after_request?.should == true
65
+ end
66
+
67
+ it "should handle the 'auto_commit_after_delete_request' propery when not set" do
68
+ @config.auto_commit_after_delete_request?.should == false
69
+ end
70
+ end
71
+
72
+ describe Sunspot::Rails::Configuration, "user provided sunspot.yml" do
73
+ before(:each) do
74
+ ::Rails.stub!(:env => 'config_test')
75
+ @config = Sunspot::Rails::Configuration.new
76
+ end
77
+
78
+ it "should handle the 'hostname' property when set" do
79
+ @config.hostname.should == 'some.host'
80
+ end
81
+
82
+ it "should handle the 'port' property when set" do
83
+ @config.port.should == 1234
84
+ end
85
+
86
+ it "should handle the 'path' property when set" do
87
+ @config.path.should == '/solr/idx'
88
+ end
89
+
90
+ it "should handle the 'log_level' propery when set" do
91
+ @config.log_level.should == 'WARNING'
92
+ end
93
+
94
+ it "should handle the 'solr_home' propery when set" do
95
+ @config.solr_home.should == '/my_superior_path'
96
+ end
97
+
98
+ it "should handle the 'data_path' property when set" do
99
+ @config.data_path.should == '/my_superior_path/data'
100
+ end
101
+
102
+ it "should handle the 'pid_dir' property when set" do
103
+ @config.pid_dir.should == '/my_superior_path/pids'
104
+ end
105
+
106
+ it "should handle the 'solr_home' property when set" do
107
+ @config.solr_home.should == '/my_superior_path'
108
+ end
109
+
110
+ it "should handle the 'auto_commit_after_request' propery when set" do
111
+ @config.auto_commit_after_request?.should == false
112
+ end
113
+
114
+ it "should handle the 'auto_commit_after_delete_request' propery when set" do
115
+ @config.auto_commit_after_delete_request?.should == true
116
+ end
117
+ end
118
+
119
+
120
+ describe Sunspot::Rails::Configuration, "with ENV['SOLR_URL'] overriding sunspot.yml" do
121
+ before(:all) do
122
+ ENV['SOLR_URL'] = 'http://environment.host:5432/solr/env'
123
+ end
124
+
125
+ before(:each) do
126
+ ::Rails.stub!(:env => 'config_test')
127
+ @config = Sunspot::Rails::Configuration.new
128
+ end
129
+
130
+ after(:all) do
131
+ ENV.delete('SOLR_URL')
132
+ end
133
+
134
+ it "should handle the 'hostname' property when set" do
135
+ @config.hostname.should == 'environment.host'
136
+ end
137
+
138
+ it "should handle the 'port' property when set" do
139
+ @config.port.should == 5432
140
+ end
141
+
142
+ it "should handle the 'path' property when set" do
143
+ @config.path.should == '/solr/env'
144
+ end
145
+ end
146
+
147
+ describe Sunspot::Rails::Configuration, "with ENV['WEBSOLR_URL'] overriding sunspot.yml" do
148
+ before(:all) do
149
+ ENV['WEBSOLR_URL'] = 'http://index.websolr.test/solr/a1b2c3d4e5f'
150
+ end
151
+
152
+ before(:each) do
153
+ ::Rails.stub!(:env => 'config_test')
154
+ @config = Sunspot::Rails::Configuration.new
155
+ end
156
+
157
+ after(:all) do
158
+ ENV.delete('WEBSOLR_URL')
159
+ end
160
+
161
+ it "should handle the 'hostname' property when set" do
162
+ @config.hostname.should == 'index.websolr.test'
163
+ end
164
+
165
+ it "should handle the 'port' property when set" do
166
+ @config.port.should == 80
167
+ end
168
+
169
+ it "should handle the 'path' property when set" do
170
+ @config.path.should == '/solr/a1b2c3d4e5f'
171
+ end
172
+ end
173
+
@@ -0,0 +1,63 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'searchable with lifecycle' do
4
+ describe 'on create' do
5
+ before :each do
6
+ @post = PostWithAuto.create
7
+ Sunspot.commit
8
+ end
9
+
10
+ it 'should automatically index' do
11
+ PostWithAuto.search.results.should == [@post]
12
+ end
13
+ end
14
+
15
+ describe 'on update' do
16
+ before :each do
17
+ @post = PostWithAuto.create
18
+ @post.update_attributes(:title => 'Test 1')
19
+ Sunspot.commit
20
+ end
21
+
22
+ it 'should automatically update index' do
23
+ PostWithAuto.search { with :title, 'Test 1' }.results.should == [@post]
24
+ end
25
+
26
+ it "should index model if relevant attribute changed" do
27
+ @post = PostWithAuto.create!
28
+ @post.title = 'new title'
29
+ @post.should_receive :solr_index
30
+ @post.save!
31
+ end
32
+
33
+ it "should not index model if relevant attribute not changed" do
34
+ @post = PostWithAuto.create!
35
+ @post.updated_at = Date.tomorrow
36
+ @post.should_not_receive :solr_index
37
+ @post.save!
38
+ end
39
+ end
40
+
41
+ describe 'on destroy' do
42
+ before :each do
43
+ @post = PostWithAuto.create
44
+ @post.destroy
45
+ Sunspot.commit
46
+ end
47
+
48
+ it 'should automatically remove it from the index' do
49
+ PostWithAuto.search_ids.should be_empty
50
+ end
51
+ end
52
+ end
53
+
54
+ describe 'searchable with lifecycle - ignoring specific attributes' do
55
+ before(:each) do
56
+ @post = PostWithAuto.create
57
+ end
58
+
59
+ it "should not reindex the object on an update_at change, because it is marked as to-ignore" do
60
+ Sunspot.should_not_receive(:index).with(@post)
61
+ @post.update_attribute :updated_at, 123.seconds.from_now
62
+ end
63
+ end