pixeltrix-thinking-sphinx 1.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/LICENCE +20 -0
  2. data/README +107 -0
  3. data/lib/thinking_sphinx.rb +144 -0
  4. data/lib/thinking_sphinx/active_record.rb +245 -0
  5. data/lib/thinking_sphinx/active_record/delta.rb +74 -0
  6. data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
  7. data/lib/thinking_sphinx/active_record/search.rb +57 -0
  8. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +34 -0
  9. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +53 -0
  10. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +129 -0
  11. data/lib/thinking_sphinx/association.rb +144 -0
  12. data/lib/thinking_sphinx/attribute.rb +258 -0
  13. data/lib/thinking_sphinx/collection.rb +142 -0
  14. data/lib/thinking_sphinx/configuration.rb +236 -0
  15. data/lib/thinking_sphinx/core/string.rb +22 -0
  16. data/lib/thinking_sphinx/deltas.rb +22 -0
  17. data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
  18. data/lib/thinking_sphinx/deltas/default_delta.rb +65 -0
  19. data/lib/thinking_sphinx/deltas/delayed_delta.rb +25 -0
  20. data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +24 -0
  21. data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +27 -0
  22. data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +26 -0
  23. data/lib/thinking_sphinx/facet.rb +58 -0
  24. data/lib/thinking_sphinx/facet_collection.rb +44 -0
  25. data/lib/thinking_sphinx/field.rb +172 -0
  26. data/lib/thinking_sphinx/index.rb +414 -0
  27. data/lib/thinking_sphinx/index/builder.rb +233 -0
  28. data/lib/thinking_sphinx/index/faux_column.rb +110 -0
  29. data/lib/thinking_sphinx/rails_additions.rb +133 -0
  30. data/lib/thinking_sphinx/search.rb +638 -0
  31. data/lib/thinking_sphinx/tasks.rb +128 -0
  32. data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +136 -0
  33. data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +53 -0
  34. data/spec/unit/thinking_sphinx/active_record/search_spec.rb +107 -0
  35. data/spec/unit/thinking_sphinx/active_record_spec.rb +256 -0
  36. data/spec/unit/thinking_sphinx/association_spec.rb +247 -0
  37. data/spec/unit/thinking_sphinx/attribute_spec.rb +212 -0
  38. data/spec/unit/thinking_sphinx/collection_spec.rb +14 -0
  39. data/spec/unit/thinking_sphinx/configuration_spec.rb +136 -0
  40. data/spec/unit/thinking_sphinx/core/string_spec.rb +9 -0
  41. data/spec/unit/thinking_sphinx/field_spec.rb +145 -0
  42. data/spec/unit/thinking_sphinx/index/builder_spec.rb +5 -0
  43. data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +30 -0
  44. data/spec/unit/thinking_sphinx/index_spec.rb +54 -0
  45. data/spec/unit/thinking_sphinx/search_spec.rb +59 -0
  46. data/spec/unit/thinking_sphinx_spec.rb +129 -0
  47. data/tasks/distribution.rb +48 -0
  48. data/tasks/rails.rake +1 -0
  49. data/tasks/testing.rb +86 -0
  50. data/vendor/after_commit/LICENSE +20 -0
  51. data/vendor/after_commit/README +16 -0
  52. data/vendor/after_commit/Rakefile +22 -0
  53. data/vendor/after_commit/init.rb +5 -0
  54. data/vendor/after_commit/lib/after_commit.rb +42 -0
  55. data/vendor/after_commit/lib/after_commit/active_record.rb +91 -0
  56. data/vendor/after_commit/lib/after_commit/connection_adapters.rb +103 -0
  57. data/vendor/after_commit/test/after_commit_test.rb +53 -0
  58. data/vendor/delayed_job/lib/delayed/job.rb +251 -0
  59. data/vendor/delayed_job/lib/delayed/message_sending.rb +7 -0
  60. data/vendor/delayed_job/lib/delayed/performable_method.rb +55 -0
  61. data/vendor/delayed_job/lib/delayed/worker.rb +54 -0
  62. data/vendor/riddle/lib/riddle.rb +30 -0
  63. data/vendor/riddle/lib/riddle/client.rb +619 -0
  64. data/vendor/riddle/lib/riddle/client/filter.rb +53 -0
  65. data/vendor/riddle/lib/riddle/client/message.rb +65 -0
  66. data/vendor/riddle/lib/riddle/client/response.rb +84 -0
  67. data/vendor/riddle/lib/riddle/configuration.rb +33 -0
  68. data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +48 -0
  69. data/vendor/riddle/lib/riddle/configuration/index.rb +142 -0
  70. data/vendor/riddle/lib/riddle/configuration/indexer.rb +19 -0
  71. data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
  72. data/vendor/riddle/lib/riddle/configuration/searchd.rb +25 -0
  73. data/vendor/riddle/lib/riddle/configuration/section.rb +37 -0
  74. data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
  75. data/vendor/riddle/lib/riddle/configuration/sql_source.rb +34 -0
  76. data/vendor/riddle/lib/riddle/configuration/xml_source.rb +28 -0
  77. data/vendor/riddle/lib/riddle/controller.rb +44 -0
  78. metadata +157 -0
data/LICENCE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Pat Allan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,107 @@
1
+ = Thinking Sphinx
2
+
3
+ == Usage
4
+
5
+ First, if you haven't done so already, check out the main usage[http://ts.freelancing-gods.com/usage.html] page. Once you've done that, the next place to look for information is the specific method docs - ThinkingSphinx::Search and ThinkingSphinx::Index::Builder in particular.
6
+
7
+ Keep in mind that while Thinking Sphinx works for ActiveRecord with Merb, it doesn't yet support DataMapper (although that is planned).
8
+
9
+ == Contributing
10
+
11
+ Fork on GitHub and after you've committed tested patches, send a pull request.
12
+
13
+ To get the spec suite running, you will need to install the not-a-mock gem if you don't already have it:
14
+
15
+ git clone git://github.com/freelancing-god/not-a-mock.git
16
+ cd not-a-mock
17
+ rake gem
18
+ gem install pkg/not_a_mock-1.1.0.gem
19
+
20
+ Then install the ginger gem. The steps are the same, except that you might need to sudo the gem install:
21
+
22
+ git clone git://github.com/freelancing-god/ginger.git
23
+ cd ginger
24
+ rake gem
25
+ sudo gem install pkg/ginger-1.1.0.gem
26
+
27
+ Then set up your database:
28
+
29
+ cp spec/fixtures/database.yml.default spec/fixtures/database.yml
30
+ mysqladmin -u root create thinking_sphinx
31
+
32
+ Make sure you don't have another Sphinx daemon (searchd) running. If you do, quit it with "rake ts:stop"
33
+ in the app root.
34
+
35
+ You should now have a passing test suite from which to build your patch on.
36
+
37
+ rake spec
38
+
39
+ If you get the message "Failed to start searchd daemon", run the spec with sudo:
40
+
41
+ sudo rake spec
42
+
43
+ If you quit the spec suite before it's completed, you may be left with data in the test
44
+ database, causing the next run to have failures. Let that run complete and then try again.
45
+
46
+ == Contributors
47
+
48
+ Since I first released this library, there's been quite a few people who have submitted patches, to my immense gratitude. Others have suggested syntax changes and general improvements. So my thanks to the following people:
49
+
50
+ - Joost Hietbrink
51
+ - Jonathan Conway
52
+ - Gregory Mirzayantz
53
+ - Tung Nguyen
54
+ - Sean Cribbs
55
+ - Benoit Caccinolo
56
+ - John Barton
57
+ - Oliver Beddows
58
+ - Arthur Zapparoli
59
+ - Dusty Doris
60
+ - Marcus Crafter
61
+ - Patrick Lenz
62
+ - Björn Andreasson
63
+ - James Healy
64
+ - Jae-Jun Hwang
65
+ - Xavier Shay
66
+ - Jason Rust
67
+ - Gopal Patel
68
+ - Chris Heald
69
+ - Peter Vandenberk
70
+ - Josh French
71
+ - Andrew Bennett
72
+ - Jordan Fowler
73
+ - Seth Walker
74
+ - Joe Noon
75
+ - Wolfgang Postler
76
+ - Rick Olson
77
+ - Killian Murphy
78
+ - Morten Primdahl
79
+ - Ryan Bates
80
+ - David Eisinger
81
+ - Shay Arnett
82
+ - Minh Tran
83
+ - Jeremy Durham
84
+ - Piotr Sarnacki
85
+ - Matt Johnson
86
+ - Nicolas Blanco
87
+ - Max Lapshin
88
+ - Josh Natanson
89
+ - Philip Hallstrom
90
+ - Christian Rishøj
91
+ - Mike Flester
92
+ - Jim Remsik
93
+ - Kennon Ballou
94
+ - Henrik Nyh
95
+ - Emil Tin
96
+ - Doug Cole
97
+ - Ed Hickey
98
+ - Evan Weaver
99
+ - Thibaut Barrere
100
+ - Kristopher Chambers
101
+ - Dmitrij Smalko
102
+ - Aleksey Yeschenko
103
+ - Lachie Cox
104
+ - Lourens Naude
105
+ - Tom Davies
106
+ - Dan Pickett
107
+ - Alex Caudill
@@ -0,0 +1,144 @@
1
+ Dir[File.join(File.dirname(__FILE__), '../vendor/*/lib')].each do |path|
2
+ $LOAD_PATH.unshift path
3
+ end
4
+
5
+ require 'active_record'
6
+ require 'riddle'
7
+ require 'after_commit'
8
+
9
+ require 'thinking_sphinx/core/string'
10
+ require 'thinking_sphinx/active_record'
11
+ require 'thinking_sphinx/association'
12
+ require 'thinking_sphinx/attribute'
13
+ require 'thinking_sphinx/collection'
14
+ require 'thinking_sphinx/configuration'
15
+ require 'thinking_sphinx/facet'
16
+ require 'thinking_sphinx/facet_collection'
17
+ require 'thinking_sphinx/field'
18
+ require 'thinking_sphinx/index'
19
+ require 'thinking_sphinx/rails_additions'
20
+ require 'thinking_sphinx/search'
21
+ require 'thinking_sphinx/deltas'
22
+
23
+ require 'thinking_sphinx/adapters/abstract_adapter'
24
+ require 'thinking_sphinx/adapters/mysql_adapter'
25
+ require 'thinking_sphinx/adapters/postgresql_adapter'
26
+
27
+ ActiveRecord::Base.send(:include, ThinkingSphinx::ActiveRecord)
28
+
29
+ Merb::Plugins.add_rakefiles(
30
+ File.join(File.dirname(__FILE__), "thinking_sphinx", "tasks")
31
+ ) if defined?(Merb)
32
+
33
+ module ThinkingSphinx
34
+ module Version #:nodoc:
35
+ Major = 1
36
+ Minor = 1
37
+ Tiny = 3
38
+
39
+ String = [Major, Minor, Tiny].join('.')
40
+ end
41
+
42
+ # A ConnectionError will get thrown when a connection to Sphinx can't be
43
+ # made.
44
+ class ConnectionError < StandardError
45
+ end
46
+
47
+ # A StaleIdsException is thrown by Collection.instances_from_matches if there
48
+ # are records in Sphinx but not in the database, so the search can be retried.
49
+ class StaleIdsException < StandardError
50
+ attr_accessor :ids
51
+ def initialize(ids)
52
+ self.ids = ids
53
+ end
54
+ end
55
+
56
+ # The collection of indexed models. Keep in mind that Rails lazily loads
57
+ # its classes, so this may not actually be populated with _all_ the models
58
+ # that have Sphinx indexes.
59
+ def self.indexed_models
60
+ @@indexed_models ||= []
61
+ end
62
+
63
+ # Check if index definition is disabled.
64
+ #
65
+ def self.define_indexes?
66
+ @@define_indexes = true unless defined?(@@define_indexes)
67
+ @@define_indexes == true
68
+ end
69
+
70
+ # Enable/disable indexes - you may want to do this while migrating data.
71
+ #
72
+ # ThinkingSphinx.define_indexes = false
73
+ #
74
+ def self.define_indexes=(value)
75
+ @@define_indexes = value
76
+ end
77
+
78
+ @@deltas_enabled = nil
79
+
80
+ # Check if delta indexing is enabled.
81
+ #
82
+ def self.deltas_enabled?
83
+ @@deltas_enabled = (ThinkingSphinx::Configuration.environment != 'test') if @@deltas_enabled.nil?
84
+ @@deltas_enabled
85
+ end
86
+
87
+ # Enable/disable all delta indexing.
88
+ #
89
+ # ThinkingSphinx.deltas_enabled = false
90
+ #
91
+ def self.deltas_enabled=(value)
92
+ @@deltas_enabled = value
93
+ end
94
+
95
+ @@updates_enabled = nil
96
+
97
+ # Check if updates are enabled. True by default, unless within the test
98
+ # environment.
99
+ #
100
+ def self.updates_enabled?
101
+ @@updates_enabled = (ThinkingSphinx::Configuration.environment != 'test') if @@updates_enabled.nil?
102
+ @@updates_enabled
103
+ end
104
+
105
+ # Enable/disable updates to Sphinx
106
+ #
107
+ # ThinkingSphinx.updates_enabled = false
108
+ #
109
+ def self.updates_enabled=(value)
110
+ @@updates_enabled = value
111
+ end
112
+
113
+ @@suppress_delta_output = false
114
+
115
+ def self.suppress_delta_output?
116
+ @@suppress_delta_output
117
+ end
118
+
119
+ def self.suppress_delta_output=(value)
120
+ @@suppress_delta_output = value
121
+ end
122
+
123
+ # Checks to see if MySQL will allow simplistic GROUP BY statements. If not,
124
+ # or if not using MySQL, this will return false.
125
+ #
126
+ def self.use_group_by_shortcut?
127
+ ::ActiveRecord::ConnectionAdapters.constants.include?("MysqlAdapter") &&
128
+ ::ActiveRecord::Base.connection.is_a?(
129
+ ::ActiveRecord::ConnectionAdapters::MysqlAdapter
130
+ ) &&
131
+ ::ActiveRecord::Base.connection.select_all(
132
+ "SELECT @@global.sql_mode, @@session.sql_mode;"
133
+ ).all? { |key,value| value.nil? || value[/ONLY_FULL_GROUP_BY/].nil? }
134
+ end
135
+
136
+ def self.sphinx_running?
137
+ !!sphinx_pid
138
+ end
139
+
140
+ def self.sphinx_pid
141
+ pid_file = ThinkingSphinx::Configuration.instance.pid_file
142
+ `cat #{pid_file}`[/\d+/] if File.exists?(pid_file)
143
+ end
144
+ end
@@ -0,0 +1,245 @@
1
+ require 'thinking_sphinx/active_record/delta'
2
+ require 'thinking_sphinx/active_record/search'
3
+ require 'thinking_sphinx/active_record/has_many_association'
4
+
5
+ module ThinkingSphinx
6
+ # Core additions to ActiveRecord models - define_index for creating indexes
7
+ # for models. If you want to interrogate the index objects created for the
8
+ # model, you can use the class-level accessor :sphinx_indexes.
9
+ #
10
+ module ActiveRecord
11
+ def self.included(base)
12
+ base.class_eval do
13
+ class_inheritable_array :sphinx_indexes, :sphinx_facets
14
+ class << self
15
+ # Allows creation of indexes for Sphinx. If you don't do this, there
16
+ # isn't much point trying to search (or using this plugin at all,
17
+ # really).
18
+ #
19
+ # An example or two:
20
+ #
21
+ # define_index
22
+ # indexes :id, :as => :model_id
23
+ # indexes name
24
+ # end
25
+ #
26
+ # You can also grab fields from associations - multiple levels deep
27
+ # if necessary.
28
+ #
29
+ # define_index do
30
+ # indexes tags.name, :as => :tag
31
+ # indexes articles.content
32
+ # indexes orders.line_items.product.name, :as => :product
33
+ # end
34
+ #
35
+ # And it will automatically concatenate multiple fields:
36
+ #
37
+ # define_index do
38
+ # indexes [author.first_name, author.last_name], :as => :author
39
+ # end
40
+ #
41
+ # The #indexes method is for fields - if you want attributes, use
42
+ # #has instead. All the same rules apply - but keep in mind that
43
+ # attributes are for sorting, grouping and filtering, not searching.
44
+ #
45
+ # define_index do
46
+ # # fields ...
47
+ #
48
+ # has created_at, updated_at
49
+ # end
50
+ #
51
+ # One last feature is the delta index. This requires the model to
52
+ # have a boolean field named 'delta', and is enabled as follows:
53
+ #
54
+ # define_index do
55
+ # # fields ...
56
+ # # attributes ...
57
+ #
58
+ # set_property :delta => true
59
+ # end
60
+ #
61
+ # Check out the more detailed documentation for each of these methods
62
+ # at ThinkingSphinx::Index::Builder.
63
+ #
64
+ def define_index(&block)
65
+ return unless ThinkingSphinx.define_indexes?
66
+
67
+ self.sphinx_indexes ||= []
68
+ index = Index.new(self, &block)
69
+
70
+ self.sphinx_indexes << index
71
+ unless ThinkingSphinx.indexed_models.include?(self.name)
72
+ ThinkingSphinx.indexed_models << self.name
73
+ end
74
+
75
+ if index.delta?
76
+ before_save :toggle_delta
77
+ after_commit :index_delta
78
+ end
79
+
80
+ after_destroy :toggle_deleted
81
+
82
+ index
83
+ end
84
+ alias_method :sphinx_index, :define_index
85
+
86
+ def sphinx_index_options
87
+ sphinx_indexes.last.options
88
+ end
89
+
90
+ # Generate a unique CRC value for the model's name, to use to
91
+ # determine which Sphinx documents belong to which AR records.
92
+ #
93
+ # Really only written for internal use - but hey, if it's useful to
94
+ # you in some other way, awesome.
95
+ #
96
+ def to_crc32
97
+ self.name.to_crc32
98
+ end
99
+
100
+ def to_crc32s
101
+ (subclasses << self).collect { |klass| klass.to_crc32 }
102
+ end
103
+
104
+ def source_of_sphinx_index
105
+ possible_models = self.sphinx_indexes.collect { |index| index.model }
106
+ return self if possible_models.include?(self)
107
+
108
+ parent = self.superclass
109
+ while !possible_models.include?(parent) && parent != ::ActiveRecord::Base
110
+ parent = parent.superclass
111
+ end
112
+
113
+ return parent
114
+ end
115
+
116
+ def to_riddle(offset)
117
+ sphinx_database_adapter.setup
118
+
119
+ indexes = [to_riddle_for_core(offset)]
120
+ indexes << to_riddle_for_delta(offset) if sphinx_delta?
121
+ indexes << to_riddle_for_distributed
122
+ end
123
+
124
+ def sphinx_database_adapter
125
+ @sphinx_database_adapter ||=
126
+ ThinkingSphinx::AbstractAdapter.detect(self)
127
+ end
128
+
129
+ private
130
+
131
+ def sphinx_name
132
+ self.name.underscore.tr(':/\\', '_')
133
+ end
134
+
135
+ def sphinx_delta?
136
+ self.sphinx_indexes.any? { |index| index.delta? }
137
+ end
138
+
139
+ def to_riddle_for_core(offset)
140
+ index = Riddle::Configuration::Index.new("#{sphinx_name}_core")
141
+ index.path = File.join(
142
+ ThinkingSphinx::Configuration.instance.searchd_file_path, index.name
143
+ )
144
+
145
+ set_configuration_options_for_indexes index
146
+ set_field_settings_for_indexes index
147
+
148
+ self.sphinx_indexes.select { |ts_index|
149
+ ts_index.model == self
150
+ }.each_with_index do |ts_index, i|
151
+ index.sources << ts_index.to_riddle_for_core(offset, i)
152
+ end
153
+
154
+ index
155
+ end
156
+
157
+ def to_riddle_for_delta(offset)
158
+ index = Riddle::Configuration::Index.new("#{sphinx_name}_delta")
159
+ index.parent = "#{sphinx_name}_core"
160
+ index.path = File.join(ThinkingSphinx::Configuration.instance.searchd_file_path, index.name)
161
+
162
+ self.sphinx_indexes.each_with_index do |ts_index, i|
163
+ index.sources << ts_index.to_riddle_for_delta(offset, i) if ts_index.delta?
164
+ end
165
+
166
+ index
167
+ end
168
+
169
+ def to_riddle_for_distributed
170
+ index = Riddle::Configuration::DistributedIndex.new(sphinx_name)
171
+ index.local_indexes << "#{sphinx_name}_core"
172
+ index.local_indexes.unshift "#{sphinx_name}_delta" if sphinx_delta?
173
+ index
174
+ end
175
+
176
+ def set_configuration_options_for_indexes(index)
177
+ ThinkingSphinx::Configuration.instance.index_options.each do |key, value|
178
+ index.send("#{key}=".to_sym, value)
179
+ end
180
+
181
+ self.sphinx_indexes.each do |ts_index|
182
+ ts_index.options.each do |key, value|
183
+ index.send("#{key}=".to_sym, value) if ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s) && !value.nil?
184
+ end
185
+ end
186
+ end
187
+
188
+ def set_field_settings_for_indexes(index)
189
+ field_names = lambda { |field| field.unique_name.to_s }
190
+
191
+ self.sphinx_indexes.each do |ts_index|
192
+ index.prefix_field_names += ts_index.prefix_fields.collect(&field_names)
193
+ index.infix_field_names += ts_index.infix_fields.collect(&field_names)
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ base.send(:include, ThinkingSphinx::ActiveRecord::Delta)
200
+ base.send(:include, ThinkingSphinx::ActiveRecord::Search)
201
+
202
+ ::ActiveRecord::Associations::HasManyAssociation.send(
203
+ :include, ThinkingSphinx::ActiveRecord::HasManyAssociation
204
+ )
205
+ ::ActiveRecord::Associations::HasManyThroughAssociation.send(
206
+ :include, ThinkingSphinx::ActiveRecord::HasManyAssociation
207
+ )
208
+ end
209
+
210
+ def in_core_index?
211
+ self.class.search_for_id(
212
+ self.sphinx_document_id,
213
+ "#{self.class.source_of_sphinx_index.name.underscore.tr(':/\\', '_')}_core"
214
+ )
215
+ end
216
+
217
+ def toggle_deleted
218
+ return unless ThinkingSphinx.updates_enabled? && ThinkingSphinx.sphinx_running?
219
+
220
+ config = ThinkingSphinx::Configuration.instance
221
+ client = Riddle::Client.new config.address, config.port
222
+
223
+ client.update(
224
+ "#{self.class.sphinx_indexes.first.name}_core",
225
+ ['sphinx_deleted'],
226
+ {self.sphinx_document_id => 1}
227
+ ) if self.in_core_index?
228
+
229
+ client.update(
230
+ "#{self.class.sphinx_indexes.first.name}_delta",
231
+ ['sphinx_deleted'],
232
+ {self.sphinx_document_id => 1}
233
+ ) if ThinkingSphinx.deltas_enabled? &&
234
+ self.class.sphinx_indexes.any? { |index| index.delta? } &&
235
+ self.delta
236
+ rescue ::ThinkingSphinx::ConnectionError
237
+ # nothing
238
+ end
239
+
240
+ def sphinx_document_id
241
+ (self.id * ThinkingSphinx.indexed_models.size) +
242
+ ThinkingSphinx.indexed_models.index(self.class.source_of_sphinx_index.name)
243
+ end
244
+ end
245
+ end