thinking-sphinx 1.2.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. data/LICENCE +20 -0
  2. data/README.textile +157 -0
  3. data/VERSION.yml +4 -0
  4. data/lib/thinking_sphinx.rb +211 -0
  5. data/lib/thinking_sphinx/active_record.rb +307 -0
  6. data/lib/thinking_sphinx/active_record/attribute_updates.rb +48 -0
  7. data/lib/thinking_sphinx/active_record/delta.rb +87 -0
  8. data/lib/thinking_sphinx/active_record/has_many_association.rb +28 -0
  9. data/lib/thinking_sphinx/active_record/scopes.rb +39 -0
  10. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
  11. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
  12. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +136 -0
  13. data/lib/thinking_sphinx/association.rb +164 -0
  14. data/lib/thinking_sphinx/attribute.rb +342 -0
  15. data/lib/thinking_sphinx/class_facet.rb +15 -0
  16. data/lib/thinking_sphinx/configuration.rb +282 -0
  17. data/lib/thinking_sphinx/core/array.rb +7 -0
  18. data/lib/thinking_sphinx/core/string.rb +15 -0
  19. data/lib/thinking_sphinx/deltas.rb +30 -0
  20. data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
  21. data/lib/thinking_sphinx/deltas/default_delta.rb +68 -0
  22. data/lib/thinking_sphinx/deltas/delayed_delta.rb +30 -0
  23. data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +24 -0
  24. data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +27 -0
  25. data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +26 -0
  26. data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
  27. data/lib/thinking_sphinx/excerpter.rb +22 -0
  28. data/lib/thinking_sphinx/facet.rb +125 -0
  29. data/lib/thinking_sphinx/facet_search.rb +134 -0
  30. data/lib/thinking_sphinx/field.rb +82 -0
  31. data/lib/thinking_sphinx/index.rb +99 -0
  32. data/lib/thinking_sphinx/index/builder.rb +286 -0
  33. data/lib/thinking_sphinx/index/faux_column.rb +110 -0
  34. data/lib/thinking_sphinx/property.rb +162 -0
  35. data/lib/thinking_sphinx/rails_additions.rb +150 -0
  36. data/lib/thinking_sphinx/search.rb +707 -0
  37. data/lib/thinking_sphinx/search_methods.rb +421 -0
  38. data/lib/thinking_sphinx/source.rb +150 -0
  39. data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
  40. data/lib/thinking_sphinx/source/sql.rb +128 -0
  41. data/lib/thinking_sphinx/tasks.rb +165 -0
  42. data/rails/init.rb +14 -0
  43. data/spec/lib/thinking_sphinx/active_record/delta_spec.rb +130 -0
  44. data/spec/lib/thinking_sphinx/active_record/has_many_association_spec.rb +49 -0
  45. data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +96 -0
  46. data/spec/lib/thinking_sphinx/active_record_spec.rb +364 -0
  47. data/spec/lib/thinking_sphinx/association_spec.rb +239 -0
  48. data/spec/lib/thinking_sphinx/attribute_spec.rb +500 -0
  49. data/spec/lib/thinking_sphinx/configuration_spec.rb +268 -0
  50. data/spec/lib/thinking_sphinx/core/array_spec.rb +9 -0
  51. data/spec/lib/thinking_sphinx/core/string_spec.rb +9 -0
  52. data/spec/lib/thinking_sphinx/excerpter_spec.rb +49 -0
  53. data/spec/lib/thinking_sphinx/facet_search_spec.rb +176 -0
  54. data/spec/lib/thinking_sphinx/facet_spec.rb +333 -0
  55. data/spec/lib/thinking_sphinx/field_spec.rb +154 -0
  56. data/spec/lib/thinking_sphinx/index/builder_spec.rb +455 -0
  57. data/spec/lib/thinking_sphinx/index/faux_column_spec.rb +30 -0
  58. data/spec/lib/thinking_sphinx/index_spec.rb +45 -0
  59. data/spec/lib/thinking_sphinx/rails_additions_spec.rb +203 -0
  60. data/spec/lib/thinking_sphinx/search_methods_spec.rb +152 -0
  61. data/spec/lib/thinking_sphinx/search_spec.rb +1092 -0
  62. data/spec/lib/thinking_sphinx/source_spec.rb +227 -0
  63. data/spec/lib/thinking_sphinx_spec.rb +162 -0
  64. data/tasks/distribution.rb +50 -0
  65. data/tasks/rails.rake +1 -0
  66. data/tasks/testing.rb +83 -0
  67. data/vendor/after_commit/LICENSE +20 -0
  68. data/vendor/after_commit/README +16 -0
  69. data/vendor/after_commit/Rakefile +22 -0
  70. data/vendor/after_commit/init.rb +8 -0
  71. data/vendor/after_commit/lib/after_commit.rb +45 -0
  72. data/vendor/after_commit/lib/after_commit/active_record.rb +114 -0
  73. data/vendor/after_commit/lib/after_commit/connection_adapters.rb +103 -0
  74. data/vendor/after_commit/test/after_commit_test.rb +53 -0
  75. data/vendor/delayed_job/lib/delayed/job.rb +251 -0
  76. data/vendor/delayed_job/lib/delayed/message_sending.rb +7 -0
  77. data/vendor/delayed_job/lib/delayed/performable_method.rb +55 -0
  78. data/vendor/delayed_job/lib/delayed/worker.rb +54 -0
  79. data/vendor/riddle/lib/riddle.rb +30 -0
  80. data/vendor/riddle/lib/riddle/client.rb +635 -0
  81. data/vendor/riddle/lib/riddle/client/filter.rb +53 -0
  82. data/vendor/riddle/lib/riddle/client/message.rb +66 -0
  83. data/vendor/riddle/lib/riddle/client/response.rb +84 -0
  84. data/vendor/riddle/lib/riddle/configuration.rb +33 -0
  85. data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +48 -0
  86. data/vendor/riddle/lib/riddle/configuration/index.rb +142 -0
  87. data/vendor/riddle/lib/riddle/configuration/indexer.rb +19 -0
  88. data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
  89. data/vendor/riddle/lib/riddle/configuration/searchd.rb +25 -0
  90. data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
  91. data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
  92. data/vendor/riddle/lib/riddle/configuration/sql_source.rb +34 -0
  93. data/vendor/riddle/lib/riddle/configuration/xml_source.rb +28 -0
  94. data/vendor/riddle/lib/riddle/controller.rb +53 -0
  95. metadata +172 -0
@@ -0,0 +1,46 @@
1
+ module ThinkingSphinx
2
+ class Source
3
+ module InternalProperties
4
+ def add_internal_attributes_and_facets
5
+ add_internal_attribute :sphinx_internal_id, :integer, @model.primary_key_for_sphinx.to_sym
6
+ add_internal_attribute :class_crc, :integer, crc_column, true
7
+ add_internal_attribute :subclass_crcs, :multi, subclasses_to_s
8
+ add_internal_attribute :sphinx_deleted, :integer, "0"
9
+
10
+ add_internal_facet :class_crc
11
+ end
12
+
13
+ def add_internal_attribute(name, type, contents, facet = false)
14
+ return unless attribute_by_alias(name).nil?
15
+
16
+ Attribute.new(self,
17
+ ThinkingSphinx::Index::FauxColumn.new(contents),
18
+ :type => type,
19
+ :as => name,
20
+ :facet => facet,
21
+ :admin => true
22
+ )
23
+ end
24
+
25
+ def add_internal_facet(name)
26
+ return unless facet_by_alias(name).nil?
27
+
28
+ @model.sphinx_facets << ClassFacet.new(attribute_by_alias(name))
29
+ end
30
+
31
+ def attribute_by_alias(attr_alias)
32
+ @attributes.detect { |attrib| attrib.alias == attr_alias }
33
+ end
34
+
35
+ def facet_by_alias(name)
36
+ @model.sphinx_facets.detect { |facet| facet.name == name }
37
+ end
38
+
39
+ def subclasses_to_s
40
+ "'" + (@model.send(:subclasses).collect { |klass|
41
+ klass.to_crc32.to_s
42
+ } << @model.to_crc32.to_s).join(",") + "'"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,128 @@
1
+ module ThinkingSphinx
2
+ class Source
3
+ module SQL
4
+ # Generates the big SQL statement to get the data back for all the fields
5
+ # and attributes, using all the relevant association joins. If you want
6
+ # the version filtered for delta values, send through :delta => true in the
7
+ # options. Won't do much though if the index isn't set up to support a
8
+ # delta sibling.
9
+ #
10
+ # Examples:
11
+ #
12
+ # source.to_sql
13
+ # source.to_sql(:delta => true)
14
+ #
15
+ def to_sql(options={})
16
+ sql = <<-SQL
17
+ SELECT #{ sql_select_clause options[:offset] }
18
+ FROM #{ @model.quoted_table_name }
19
+ #{ all_associations.collect { |assoc| assoc.to_sql }.join(' ') }
20
+ #{ sql_where_clause(options) }
21
+ GROUP BY #{ sql_group_clause }
22
+ SQL
23
+
24
+ sql += " ORDER BY NULL" if adapter.sphinx_identifier == "mysql"
25
+ sql
26
+ end
27
+
28
+ # Simple helper method for the query range SQL - which is a statement that
29
+ # returns minimum and maximum id values. These can be filtered by delta -
30
+ # so pass in :delta => true to get the delta version of the SQL.
31
+ #
32
+ def to_sql_query_range(options={})
33
+ return nil if @index.options[:disable_range]
34
+
35
+ min_statement = adapter.convert_nulls(
36
+ "MIN(#{quote_column(@model.primary_key_for_sphinx)})", 1
37
+ )
38
+ max_statement = adapter.convert_nulls(
39
+ "MAX(#{quote_column(@model.primary_key_for_sphinx)})", 1
40
+ )
41
+
42
+ sql = "SELECT #{min_statement}, #{max_statement} " +
43
+ "FROM #{@model.quoted_table_name} "
44
+ if self.delta? && !@index.delta_object.clause(@model, options[:delta]).blank?
45
+ sql << "WHERE #{@index.delta_object.clause(@model, options[:delta])}"
46
+ end
47
+
48
+ sql
49
+ end
50
+
51
+ # Simple helper method for the query info SQL - which is a statement that
52
+ # returns the single row for a corresponding id.
53
+ #
54
+ def to_sql_query_info(offset)
55
+ "SELECT * FROM #{@model.quoted_table_name} WHERE " +
56
+ "#{quote_column(@model.primary_key_for_sphinx)} = (($id - #{offset}) / #{ThinkingSphinx.indexed_models.size})"
57
+ end
58
+
59
+ def sql_select_clause(offset)
60
+ unique_id_expr = ThinkingSphinx.unique_id_expression(offset)
61
+
62
+ (
63
+ ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} #{unique_id_expr} AS #{quote_column(@model.primary_key_for_sphinx)} "] +
64
+ @fields.collect { |field| field.to_select_sql } +
65
+ @attributes.collect { |attribute| attribute.to_select_sql }
66
+ ).compact.join(", ")
67
+ end
68
+
69
+ def sql_where_clause(options)
70
+ logic = []
71
+ logic += [
72
+ "#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} >= $start",
73
+ "#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} <= $end"
74
+ ] unless @index.options[:disable_range]
75
+
76
+ if self.delta? && !@index.delta_object.clause(@model, options[:delta]).blank?
77
+ logic << "#{@index.delta_object.clause(@model, options[:delta])}"
78
+ end
79
+
80
+ logic += (@conditions || [])
81
+ logic.empty? ? "" : "WHERE #{logic.join(' AND ')}"
82
+ end
83
+
84
+ def sql_group_clause
85
+ internal_groupings = []
86
+ if @model.column_names.include?(@model.inheritance_column)
87
+ internal_groupings << "#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)}"
88
+ end
89
+
90
+ (
91
+ ["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)}"] +
92
+ @fields.collect { |field| field.to_group_sql }.compact +
93
+ @attributes.collect { |attribute| attribute.to_group_sql }.compact +
94
+ @groupings + internal_groupings
95
+ ).join(", ")
96
+ end
97
+
98
+ def sql_query_pre_for_core
99
+ if self.delta? && !@index.delta_object.reset_query(@model).blank?
100
+ [@index.delta_object.reset_query(@model)]
101
+ else
102
+ []
103
+ end
104
+ end
105
+
106
+ def sql_query_pre_for_delta
107
+ [""]
108
+ end
109
+
110
+ def quote_column(column)
111
+ @model.connection.quote_column_name(column)
112
+ end
113
+
114
+ def crc_column
115
+ if @model.table_exists? &&
116
+ @model.column_names.include?(@model.inheritance_column)
117
+
118
+ adapter.cast_to_unsigned(adapter.convert_nulls(
119
+ adapter.crc(adapter.quote_with_table(@model.inheritance_column), true),
120
+ @model.to_crc32
121
+ ))
122
+ else
123
+ @model.to_crc32.to_s
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,165 @@
1
+ require 'fileutils'
2
+
3
+ namespace :thinking_sphinx do
4
+ task :app_env do
5
+ if defined?(RAILS_ROOT)
6
+ Rake::Task[:environment].invoke
7
+ Rails.configuration.cache_classes = false
8
+ end
9
+
10
+ Rake::Task[:merb_env].invoke if defined?(Merb)
11
+ end
12
+
13
+ desc "Output the current Thinking Sphinx version"
14
+ task :version => :app_env do
15
+ puts "Thinking Sphinx v" + ThinkingSphinx.version
16
+ end
17
+
18
+ desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
19
+ task :running_start => :app_env do
20
+ Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
21
+ Rake::Task["thinking_sphinx:start"].invoke
22
+ end
23
+
24
+ desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
25
+ task :start => :app_env do
26
+ config = ThinkingSphinx::Configuration.instance
27
+
28
+ FileUtils.mkdir_p config.searchd_file_path
29
+ raise RuntimeError, "searchd is already running." if sphinx_running?
30
+
31
+ Dir["#{config.searchd_file_path}/*.spl"].each { |file| File.delete(file) }
32
+
33
+ system! "#{config.bin_path}#{config.searchd_binary_name} --pidfile --config \"#{config.config_file}\""
34
+
35
+ sleep(2)
36
+
37
+ if sphinx_running?
38
+ puts "Started successfully (pid #{sphinx_pid})."
39
+ else
40
+ puts "Failed to start searchd daemon. Check #{config.searchd_log_file}"
41
+ end
42
+ end
43
+
44
+ desc "Stop Sphinx using Thinking Sphinx's settings"
45
+ task :stop => :app_env do
46
+ unless sphinx_running?
47
+ puts "searchd is not running"
48
+ else
49
+ config = ThinkingSphinx::Configuration.instance
50
+ pid = sphinx_pid
51
+ system! "#{config.bin_path}#{config.searchd_binary_name} --stop --config \"#{config.config_file}\""
52
+ puts "Stopped search daemon (pid #{pid})."
53
+ end
54
+ end
55
+
56
+ desc "Restart Sphinx"
57
+ task :restart => [:app_env, :stop, :start]
58
+
59
+ desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
60
+ task :configure => :app_env do
61
+ config = ThinkingSphinx::Configuration.instance
62
+ puts "Generating Configuration to #{config.config_file}"
63
+ config.build
64
+ end
65
+
66
+ desc "Index data for Sphinx using Thinking Sphinx's settings"
67
+ task :index => :app_env do
68
+ ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
69
+
70
+ config = ThinkingSphinx::Configuration.instance
71
+ unless ENV["INDEX_ONLY"] == "true"
72
+ puts "Generating Configuration to #{config.config_file}"
73
+ config.build
74
+ end
75
+
76
+ FileUtils.mkdir_p config.searchd_file_path
77
+ cmd = "#{config.bin_path}#{config.indexer_binary_name} --config \"#{config.config_file}\" --all"
78
+ cmd << " --rotate" if sphinx_running?
79
+
80
+ system! cmd
81
+ end
82
+
83
+ desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
84
+ task :rebuild => :app_env do
85
+ Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
86
+ Rake::Task["thinking_sphinx:index"].invoke
87
+ Rake::Task["thinking_sphinx:start"].invoke
88
+ end
89
+
90
+ namespace :index do
91
+ task :delta => :app_env do
92
+ ThinkingSphinx.indexed_models.select { |model|
93
+ model.constantize.sphinx_indexes.any? { |index| index.delta? }
94
+ }.each do |model|
95
+ model.constantize.sphinx_indexes.select { |index|
96
+ index.delta? && index.delta_object.respond_to?(:delayed_index)
97
+ }.each { |index|
98
+ index.delta_object.delayed_index(index.model)
99
+ }
100
+ end
101
+ end
102
+ end
103
+
104
+ desc "Process stored delta index requests"
105
+ task :delayed_delta => :app_env do
106
+ require 'delayed/worker'
107
+
108
+ Delayed::Worker.new(
109
+ :min_priority => ENV['MIN_PRIORITY'],
110
+ :max_priority => ENV['MAX_PRIORITY']
111
+ ).start
112
+ end
113
+ end
114
+
115
+ namespace :ts do
116
+ desc "Output the current Thinking Sphinx version"
117
+ task :version => "thinking_sphinx:version"
118
+ desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
119
+ task :run => "thinking_sphinx:running_start"
120
+ desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
121
+ task :start => "thinking_sphinx:start"
122
+ desc "Stop Sphinx using Thinking Sphinx's settings"
123
+ task :stop => "thinking_sphinx:stop"
124
+ desc "Index data for Sphinx using Thinking Sphinx's settings"
125
+ task :in => "thinking_sphinx:index"
126
+ namespace :in do
127
+ desc "Index Thinking Sphinx datetime delta indexes"
128
+ task :delta => "thinking_sphinx:index:delta"
129
+ end
130
+ task :index => "thinking_sphinx:index"
131
+ desc "Restart Sphinx"
132
+ task :restart => "thinking_sphinx:restart"
133
+ desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
134
+ task :conf => "thinking_sphinx:configure"
135
+ desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
136
+ task :config => "thinking_sphinx:configure"
137
+ desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
138
+ task :rebuild => "thinking_sphinx:rebuild"
139
+ desc "Process stored delta index requests"
140
+ task :dd => "thinking_sphinx:delayed_delta"
141
+ end
142
+
143
+ def sphinx_pid
144
+ ThinkingSphinx.sphinx_pid
145
+ end
146
+
147
+ def sphinx_running?
148
+ ThinkingSphinx.sphinx_running?
149
+ end
150
+
151
+ # a fail-fast, hopefully helpful version of system
152
+ def system!(cmd)
153
+ unless system(cmd)
154
+ raise <<-SYSTEM_CALL_FAILED
155
+ The following command failed:
156
+ #{cmd}
157
+
158
+ This could be caused by a PATH issue in the environment of cron/passenger/etc. Your current PATH:
159
+ #{ENV['PATH']}
160
+ You can set the path to your indexer and searchd binaries using the bin_path property in config/sphinx.yml:
161
+ production:
162
+ bin_path: '/usr/local/bin'
163
+ SYSTEM_CALL_FAILED
164
+ end
165
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'thinking_sphinx'
2
+ require 'action_controller/dispatcher'
3
+
4
+ ActionController::Dispatcher.to_prepare :thinking_sphinx do
5
+ # Force internationalisation to be loaded.
6
+ if Rails::VERSION::STRING.to_f > 2.2
7
+ I18n.backend.reload!
8
+ I18n.backend.available_locales
9
+ elsif Rails::VERSION::STRING.to_f > 2.1
10
+ I18n.backend.load_translations(*I18n.load_path)
11
+ end
12
+
13
+ ThinkingSphinx::Configuration.instance.load_models
14
+ end
@@ -0,0 +1,130 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe "ThinkingSphinx::ActiveRecord::Delta" do
4
+ it "should call the toggle_delta method after a save" do
5
+ @beta = Beta.new(:name => 'beta')
6
+ @beta.should_receive(:toggle_delta).and_return(true)
7
+
8
+ @beta.save
9
+ end
10
+
11
+ it "should call the toggle_delta method after a save!" do
12
+ @beta = Beta.new(:name => 'beta')
13
+ @beta.should_receive(:toggle_delta).and_return(true)
14
+
15
+ @beta.save!
16
+ end
17
+
18
+ describe "suspended_delta method" do
19
+ before :each do
20
+ ThinkingSphinx.deltas_enabled = true
21
+ Person.sphinx_indexes.first.delta_object.stub!(:` => "")
22
+ end
23
+
24
+ it "should execute the argument block with deltas disabled" do
25
+ ThinkingSphinx.should_receive(:deltas_enabled=).once.with(false)
26
+ ThinkingSphinx.should_receive(:deltas_enabled=).once.with(true)
27
+ lambda { Person.suspended_delta { raise 'i was called' } }.should(
28
+ raise_error(Exception)
29
+ )
30
+ end
31
+
32
+ it "should restore deltas_enabled to its original setting" do
33
+ ThinkingSphinx.deltas_enabled = false
34
+ ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false)
35
+ Person.suspended_delta { 'no-op' }
36
+ end
37
+
38
+ it "should restore deltas_enabled to its original setting even if there was an exception" do
39
+ ThinkingSphinx.deltas_enabled = false
40
+ ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false)
41
+ lambda { Person.suspended_delta { raise 'bad error' } }.should(
42
+ raise_error(Exception)
43
+ )
44
+ end
45
+
46
+ it "should reindex by default after the code block is run" do
47
+ Person.should_receive(:index_delta)
48
+ Person.suspended_delta { 'no-op' }
49
+ end
50
+
51
+ it "should not reindex after the code block if false is passed in" do
52
+ Person.should_not_receive(:index_delta)
53
+ Person.suspended_delta(false) { 'no-op' }
54
+ end
55
+ end
56
+
57
+ describe "toggle_delta method" do
58
+ it "should set the delta value to true" do
59
+ @person = Person.new
60
+
61
+ @person.delta.should be_false
62
+ @person.send(:toggle_delta)
63
+ @person.delta.should be_true
64
+ end
65
+ end
66
+
67
+ describe "index_delta method" do
68
+ before :each do
69
+ ThinkingSphinx::Configuration.stub!(:environment => "spec")
70
+ ThinkingSphinx.deltas_enabled = true
71
+ ThinkingSphinx.updates_enabled = true
72
+ ThinkingSphinx.stub!(:sphinx_running? => true)
73
+ Person.delta_object.stub!(:` => "", :toggled => true)
74
+
75
+ @person = Person.new
76
+ @person.stub!(
77
+ :in_both_indexes? => false,
78
+ :sphinx_document_id => 1
79
+ )
80
+
81
+ @client = Riddle::Client.new
82
+ @client.stub!(:update => true)
83
+ Riddle::Client.stub!(:new => @client)
84
+ end
85
+
86
+ it "shouldn't index if delta indexing is disabled" do
87
+ ThinkingSphinx.deltas_enabled = false
88
+ Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
89
+ @client.should_not_receive(:update)
90
+
91
+ @person.send(:index_delta)
92
+ end
93
+
94
+ it "shouldn't index if index updating is disabled" do
95
+ ThinkingSphinx.updates_enabled = false
96
+ Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
97
+
98
+ @person.send(:index_delta)
99
+ end
100
+
101
+ it "shouldn't index if the environment is 'test'" do
102
+ ThinkingSphinx.deltas_enabled = nil
103
+ ThinkingSphinx::Configuration.stub!(:environment => "test")
104
+ Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
105
+
106
+ @person.send(:index_delta)
107
+ end
108
+
109
+ it "should call indexer for the delta index" do
110
+ Person.sphinx_indexes.first.delta_object.should_receive(:`).with(
111
+ "#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config #{ThinkingSphinx::Configuration.instance.config_file} --rotate person_delta"
112
+ )
113
+
114
+ @person.send(:index_delta)
115
+ end
116
+
117
+ it "shouldn't update the deleted attribute if not in the index" do
118
+ @client.should_not_receive(:update)
119
+
120
+ @person.send(:index_delta)
121
+ end
122
+
123
+ it "should update the deleted attribute if in the core index" do
124
+ @person.stub!(:in_both_indexes? => true)
125
+ @client.should_receive(:update)
126
+
127
+ @person.send(:index_delta)
128
+ end
129
+ end
130
+ end