substantial-sunspot_rails 2.0.0.pre.111215
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.
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/History.txt +66 -0
- data/LICENSE +18 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +265 -0
- data/Rakefile +12 -0
- data/TODO +8 -0
- data/dev_tasks/rdoc.rake +24 -0
- data/dev_tasks/release.rake +4 -0
- data/dev_tasks/spec.rake +107 -0
- data/dev_tasks/todo.rake +4 -0
- data/gemfiles/rails-2.3.14 +15 -0
- data/gemfiles/rails-3.0.11 +15 -0
- data/gemfiles/rails-3.1.3 +15 -0
- data/generators/sunspot/sunspot_generator.rb +9 -0
- data/generators/sunspot/templates/sunspot.yml +18 -0
- data/install.rb +1 -0
- data/lib/generators/sunspot_rails.rb +9 -0
- data/lib/generators/sunspot_rails/install/install_generator.rb +13 -0
- data/lib/generators/sunspot_rails/install/templates/config/sunspot.yml +17 -0
- data/lib/substantial-sunspot_rails.rb +1 -0
- data/lib/sunspot/rails.rb +65 -0
- data/lib/sunspot/rails/adapters.rb +83 -0
- data/lib/sunspot/rails/configuration.rb +340 -0
- data/lib/sunspot/rails/init.rb +5 -0
- data/lib/sunspot/rails/log_subscriber.rb +33 -0
- data/lib/sunspot/rails/railtie.rb +36 -0
- data/lib/sunspot/rails/railties/controller_runtime.rb +36 -0
- data/lib/sunspot/rails/request_lifecycle.rb +36 -0
- data/lib/sunspot/rails/searchable.rb +480 -0
- data/lib/sunspot/rails/server.rb +106 -0
- data/lib/sunspot/rails/solr_instrumentation.rb +18 -0
- data/lib/sunspot/rails/solr_logging.rb +62 -0
- data/lib/sunspot/rails/spec_helper.rb +26 -0
- data/lib/sunspot/rails/stub_session_proxy.rb +142 -0
- data/lib/sunspot/rails/tasks.rb +84 -0
- data/lib/sunspot_rails.rb +12 -0
- data/spec/configuration_spec.rb +195 -0
- data/spec/model_lifecycle_spec.rb +63 -0
- data/spec/model_spec.rb +595 -0
- data/spec/rails_template/app/controllers/application_controller.rb +10 -0
- data/spec/rails_template/app/controllers/posts_controller.rb +6 -0
- data/spec/rails_template/app/models/author.rb +8 -0
- data/spec/rails_template/app/models/blog.rb +12 -0
- data/spec/rails_template/app/models/location.rb +2 -0
- data/spec/rails_template/app/models/photo_post.rb +2 -0
- data/spec/rails_template/app/models/post.rb +11 -0
- data/spec/rails_template/app/models/post_with_auto.rb +10 -0
- data/spec/rails_template/app/models/post_with_default_scope.rb +11 -0
- data/spec/rails_template/config/boot.rb +127 -0
- data/spec/rails_template/config/preinitializer.rb +22 -0
- data/spec/rails_template/config/routes.rb +9 -0
- data/spec/rails_template/config/sunspot.yml +22 -0
- data/spec/rails_template/db/schema.rb +27 -0
- data/spec/request_lifecycle_spec.rb +61 -0
- data/spec/schema.rb +27 -0
- data/spec/searchable_spec.rb +12 -0
- data/spec/server_spec.rb +33 -0
- data/spec/session_spec.rb +57 -0
- data/spec/shared_examples/indexed_after_save.rb +8 -0
- data/spec/shared_examples/not_indexed_after_save.rb +8 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/stub_session_proxy_spec.rb +122 -0
- data/substantial-sunspot_rails.gemspec +43 -0
- metadata +228 -0
@@ -0,0 +1,106 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Rails
|
3
|
+
class Server < Sunspot::Solr::Server
|
4
|
+
# ActiveSupport log levels are integers; this array maps them to the
|
5
|
+
# appropriate java.util.logging.Level constant
|
6
|
+
LOG_LEVELS = %w(FINE INFO WARNING SEVERE SEVERE INFO)
|
7
|
+
|
8
|
+
#
|
9
|
+
# Directory in which to store PID files
|
10
|
+
#
|
11
|
+
def pid_dir
|
12
|
+
configuration.pid_dir || File.join(::Rails.root, 'tmp', 'pids')
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Name of the PID file
|
17
|
+
#
|
18
|
+
def pid_file
|
19
|
+
"sunspot-solr-#{::Rails.env}.pid"
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Directory to store lucene index data files
|
24
|
+
#
|
25
|
+
# ==== Returns
|
26
|
+
#
|
27
|
+
# String:: data_path
|
28
|
+
#
|
29
|
+
def solr_data_dir
|
30
|
+
configuration.data_path
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Directory to use for Solr home.
|
35
|
+
#
|
36
|
+
def solr_home
|
37
|
+
File.join(configuration.solr_home)
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Solr start jar
|
42
|
+
#
|
43
|
+
def solr_jar
|
44
|
+
configuration.solr_jar || super
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Address on which to run Solr
|
49
|
+
#
|
50
|
+
def bind_address
|
51
|
+
configuration.bind_address
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Port on which to run Solr
|
56
|
+
#
|
57
|
+
def port
|
58
|
+
configuration.port
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Severity level for logging. This is based on the severity level for the
|
63
|
+
# Rails logger.
|
64
|
+
#
|
65
|
+
def log_level
|
66
|
+
LOG_LEVELS[::Rails.logger.level]
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Log file for Solr. File is in the rails log/ directory.
|
71
|
+
#
|
72
|
+
def log_file
|
73
|
+
File.join(::Rails.root, 'log', "sunspot-solr-#{::Rails.env}.log")
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# Minimum Java heap size for Solr
|
78
|
+
#
|
79
|
+
def min_memory
|
80
|
+
configuration.min_memory
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Maximum Java heap size for Solr
|
85
|
+
#
|
86
|
+
def max_memory
|
87
|
+
configuration.max_memory
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
#
|
93
|
+
# access to the Sunspot::Rails::Configuration, defined in
|
94
|
+
# sunspot.yml. Use Sunspot::Rails.configuration if you want
|
95
|
+
# to access the configuration directly.
|
96
|
+
#
|
97
|
+
# ==== returns
|
98
|
+
#
|
99
|
+
# Sunspot::Rails::Configuration:: configuration
|
100
|
+
#
|
101
|
+
def configuration
|
102
|
+
Sunspot::Rails.configuration
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Rails
|
3
|
+
module SolrInstrumentation
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
alias_method_chain :execute, :as_instrumentation
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute_with_as_instrumentation(path, params={}, *extra)
|
11
|
+
ActiveSupport::Notifications.instrument("request.rsolr",
|
12
|
+
{:path => path, :parameters => params}) do
|
13
|
+
execute_without_as_instrumentation(path, params, *extra)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Rails
|
3
|
+
module SolrLogging
|
4
|
+
|
5
|
+
class <<self
|
6
|
+
def included(base)
|
7
|
+
base.alias_method_chain :execute, :rails_logging
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
COMMIT = %r{<commit/>}
|
12
|
+
|
13
|
+
def execute_with_rails_logging(client, request_context)
|
14
|
+
body = (request_context[:data]||"").dup
|
15
|
+
action = request_context[:path].capitalize
|
16
|
+
if body =~ COMMIT
|
17
|
+
action = "Commit"
|
18
|
+
body = ""
|
19
|
+
end
|
20
|
+
body = body[0, 800] + '...' if body.length > 800
|
21
|
+
|
22
|
+
# Make request and log.
|
23
|
+
response = nil
|
24
|
+
begin
|
25
|
+
ms = Benchmark.ms do
|
26
|
+
response = execute_without_rails_logging(client, request_context)
|
27
|
+
end
|
28
|
+
log_name = 'Solr %s (%.1fms)' % [action, ms]
|
29
|
+
::Rails.logger.debug(format_log_entry(log_name, body))
|
30
|
+
rescue Exception => e
|
31
|
+
log_name = 'Solr %s (Error)' % [action]
|
32
|
+
::Rails.logger.error(format_log_entry(log_name, body))
|
33
|
+
raise e
|
34
|
+
end
|
35
|
+
|
36
|
+
response
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def format_log_entry(message, dump = nil)
|
42
|
+
@colorize_logging ||= begin
|
43
|
+
::Rails.application.config.colorize_logging # Rails 3
|
44
|
+
rescue NoMethodError
|
45
|
+
ActiveRecord::Base.colorize_logging # Rails 2
|
46
|
+
end
|
47
|
+
if @colorize_logging
|
48
|
+
message_color, dump_color = "4;32;1", "0;1"
|
49
|
+
log_entry = " \e[#{message_color}m#{message}\e[0m "
|
50
|
+
log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
|
51
|
+
log_entry
|
52
|
+
else
|
53
|
+
"%s %s" % [message, dump]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
RSolr::Connection.module_eval do
|
61
|
+
include Sunspot::Rails::SolrLogging
|
62
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Sunspot
|
2
|
+
module Rails
|
3
|
+
module SpecHelper
|
4
|
+
def disconnect_sunspot
|
5
|
+
before(:each) do
|
6
|
+
Sunspot.session = StubSessionProxy.new(Sunspot.session)
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
Sunspot.session = Sunspot.session.original_session
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
rspec =
|
18
|
+
begin
|
19
|
+
RSpec
|
20
|
+
rescue NameError, ArgumentError
|
21
|
+
Spec::Runner
|
22
|
+
end
|
23
|
+
|
24
|
+
rspec.configure do |config|
|
25
|
+
config.extend(Sunspot::Rails::SpecHelper)
|
26
|
+
end
|
@@ -0,0 +1,142 @@
|
|
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
|
+
def new_more_like_this(*args)
|
60
|
+
Search.new
|
61
|
+
end
|
62
|
+
|
63
|
+
class Search
|
64
|
+
|
65
|
+
def build
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def results
|
70
|
+
PaginatedCollection.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def hits(options = {})
|
74
|
+
PaginatedCollection.new
|
75
|
+
end
|
76
|
+
|
77
|
+
def total
|
78
|
+
0
|
79
|
+
end
|
80
|
+
|
81
|
+
def facet(name)
|
82
|
+
end
|
83
|
+
|
84
|
+
def dynamic_facet(name)
|
85
|
+
end
|
86
|
+
|
87
|
+
def execute
|
88
|
+
self
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
class PaginatedCollection < Array
|
94
|
+
|
95
|
+
def total_count
|
96
|
+
0
|
97
|
+
end
|
98
|
+
alias :total_entries :total_count
|
99
|
+
|
100
|
+
def current_page
|
101
|
+
1
|
102
|
+
end
|
103
|
+
|
104
|
+
def per_page
|
105
|
+
30
|
106
|
+
end
|
107
|
+
alias :limit_value :per_page
|
108
|
+
|
109
|
+
def total_pages
|
110
|
+
1
|
111
|
+
end
|
112
|
+
alias :num_pages :total_pages
|
113
|
+
|
114
|
+
def first_page?
|
115
|
+
true
|
116
|
+
end
|
117
|
+
|
118
|
+
def last_page?
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
122
|
+
def previous_page
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
|
126
|
+
def next_page
|
127
|
+
nil
|
128
|
+
end
|
129
|
+
|
130
|
+
def out_of_bounds?
|
131
|
+
false
|
132
|
+
end
|
133
|
+
|
134
|
+
def offset
|
135
|
+
0
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
namespace :sunspot do
|
2
|
+
|
3
|
+
desc "Reindex all solr models that are located in your application's models directory."
|
4
|
+
# This task depends on the standard Rails file naming \
|
5
|
+
# conventions, in that the file name matches the defined class name. \
|
6
|
+
# By default the indexing system works in batches of 50 records, you can \
|
7
|
+
# set your own value for this by using the batch_size argument. You can \
|
8
|
+
# also optionally define a list of models to separated by a forward slash '/'
|
9
|
+
#
|
10
|
+
# $ rake sunspot:reindex # reindex all models
|
11
|
+
# $ rake sunspot:reindex[1000] # reindex in batches of 1000
|
12
|
+
# $ rake sunspot:reindex[false] # reindex without batching
|
13
|
+
# $ rake sunspot:reindex[,Post] # reindex only the Post model
|
14
|
+
# $ rake sunspot:reindex[1000,Post] # reindex only the Post model in
|
15
|
+
# # batchs of 1000
|
16
|
+
# $ rake sunspot:reindex[,Post+Author] # reindex Post and Author model
|
17
|
+
task :reindex, [:batch_size, :models] => [:environment] do |t, args|
|
18
|
+
# Set up general options for reindexing
|
19
|
+
reindex_options = { :batch_commit => false }
|
20
|
+
|
21
|
+
case args[:batch_size]
|
22
|
+
when 'false'
|
23
|
+
reindex_options[:batch_size] = nil
|
24
|
+
when /^\d+$/
|
25
|
+
reindex_options[:batch_size] = args[:batch_size].to_i if args[:batch_size].to_i > 0
|
26
|
+
end
|
27
|
+
|
28
|
+
# Load all the application's models. Models which invoke 'searchable' will register themselves
|
29
|
+
# in Sunspot.searchable.
|
30
|
+
Dir.glob(Rails.root.join('app/models/**/*.rb')).each { |path| require path }
|
31
|
+
|
32
|
+
# By default, reindex all searchable models
|
33
|
+
sunspot_models = Sunspot.searchable
|
34
|
+
|
35
|
+
# Choose a specific subset of models, if requested
|
36
|
+
if args[:models]
|
37
|
+
model_names = args[:models].split('+')
|
38
|
+
sunspot_models = model_names.map{ |m| m.constantize }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Set up progress_bar to, ah, report progress
|
42
|
+
begin
|
43
|
+
require 'progress_bar'
|
44
|
+
total_documents = sunspot_models.map { | m | m.count }.sum
|
45
|
+
reindex_options[:progress_bar] = ProgressBar.new(total_documents)
|
46
|
+
rescue LoadError => e
|
47
|
+
$stderr.puts "Skipping progress bar: for progress reporting, add gem 'progress_bar' to your Gemfile"
|
48
|
+
rescue Exception => e
|
49
|
+
$stderr.puts "Error using progress bar: #{e.message}"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Finally, invoke the class-level solr_reindex on each model
|
53
|
+
sunspot_models.each do |model|
|
54
|
+
model.solr_reindex(reindex_options)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
unless defined?(Sunspot::Solr)
|
60
|
+
namespace :solr do
|
61
|
+
task :moved_to_sunspot_solr do
|
62
|
+
abort %(
|
63
|
+
Note: This task has been moved to the sunspot_solr gem. To install, start and
|
64
|
+
stop a local Solr instance, please add sunspot_solr to your Gemfile:
|
65
|
+
|
66
|
+
group :development do
|
67
|
+
gem 'sunspot_solr'
|
68
|
+
end
|
69
|
+
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
desc 'Start the Solr instance'
|
74
|
+
task :start => :moved_to_sunspot_solr
|
75
|
+
desc 'Run the Solr instance in the foreground'
|
76
|
+
task :run => :moved_to_sunspot_solr
|
77
|
+
desc 'Stop the Solr instance'
|
78
|
+
task :stop => :moved_to_sunspot_solr
|
79
|
+
# for backwards compatibility
|
80
|
+
task :reindex => :"sunspot:reindex"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
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
|