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.
Files changed (66) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +1 -0
  3. data/History.txt +66 -0
  4. data/LICENSE +18 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +265 -0
  7. data/Rakefile +12 -0
  8. data/TODO +8 -0
  9. data/dev_tasks/rdoc.rake +24 -0
  10. data/dev_tasks/release.rake +4 -0
  11. data/dev_tasks/spec.rake +107 -0
  12. data/dev_tasks/todo.rake +4 -0
  13. data/gemfiles/rails-2.3.14 +15 -0
  14. data/gemfiles/rails-3.0.11 +15 -0
  15. data/gemfiles/rails-3.1.3 +15 -0
  16. data/generators/sunspot/sunspot_generator.rb +9 -0
  17. data/generators/sunspot/templates/sunspot.yml +18 -0
  18. data/install.rb +1 -0
  19. data/lib/generators/sunspot_rails.rb +9 -0
  20. data/lib/generators/sunspot_rails/install/install_generator.rb +13 -0
  21. data/lib/generators/sunspot_rails/install/templates/config/sunspot.yml +17 -0
  22. data/lib/substantial-sunspot_rails.rb +1 -0
  23. data/lib/sunspot/rails.rb +65 -0
  24. data/lib/sunspot/rails/adapters.rb +83 -0
  25. data/lib/sunspot/rails/configuration.rb +340 -0
  26. data/lib/sunspot/rails/init.rb +5 -0
  27. data/lib/sunspot/rails/log_subscriber.rb +33 -0
  28. data/lib/sunspot/rails/railtie.rb +36 -0
  29. data/lib/sunspot/rails/railties/controller_runtime.rb +36 -0
  30. data/lib/sunspot/rails/request_lifecycle.rb +36 -0
  31. data/lib/sunspot/rails/searchable.rb +480 -0
  32. data/lib/sunspot/rails/server.rb +106 -0
  33. data/lib/sunspot/rails/solr_instrumentation.rb +18 -0
  34. data/lib/sunspot/rails/solr_logging.rb +62 -0
  35. data/lib/sunspot/rails/spec_helper.rb +26 -0
  36. data/lib/sunspot/rails/stub_session_proxy.rb +142 -0
  37. data/lib/sunspot/rails/tasks.rb +84 -0
  38. data/lib/sunspot_rails.rb +12 -0
  39. data/spec/configuration_spec.rb +195 -0
  40. data/spec/model_lifecycle_spec.rb +63 -0
  41. data/spec/model_spec.rb +595 -0
  42. data/spec/rails_template/app/controllers/application_controller.rb +10 -0
  43. data/spec/rails_template/app/controllers/posts_controller.rb +6 -0
  44. data/spec/rails_template/app/models/author.rb +8 -0
  45. data/spec/rails_template/app/models/blog.rb +12 -0
  46. data/spec/rails_template/app/models/location.rb +2 -0
  47. data/spec/rails_template/app/models/photo_post.rb +2 -0
  48. data/spec/rails_template/app/models/post.rb +11 -0
  49. data/spec/rails_template/app/models/post_with_auto.rb +10 -0
  50. data/spec/rails_template/app/models/post_with_default_scope.rb +11 -0
  51. data/spec/rails_template/config/boot.rb +127 -0
  52. data/spec/rails_template/config/preinitializer.rb +22 -0
  53. data/spec/rails_template/config/routes.rb +9 -0
  54. data/spec/rails_template/config/sunspot.yml +22 -0
  55. data/spec/rails_template/db/schema.rb +27 -0
  56. data/spec/request_lifecycle_spec.rb +61 -0
  57. data/spec/schema.rb +27 -0
  58. data/spec/searchable_spec.rb +12 -0
  59. data/spec/server_spec.rb +33 -0
  60. data/spec/session_spec.rb +57 -0
  61. data/spec/shared_examples/indexed_after_save.rb +8 -0
  62. data/spec/shared_examples/not_indexed_after_save.rb +8 -0
  63. data/spec/spec_helper.rb +48 -0
  64. data/spec/stub_session_proxy_spec.rb +122 -0
  65. data/substantial-sunspot_rails.gemspec +43 -0
  66. 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