angelf-thinking-sphinx 1.3.18

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 (159) hide show
  1. data/LICENCE +20 -0
  2. data/README.textile +170 -0
  3. data/VERSION +1 -0
  4. data/features/abstract_inheritance.feature +10 -0
  5. data/features/alternate_primary_key.feature +27 -0
  6. data/features/attribute_transformation.feature +22 -0
  7. data/features/attribute_updates.feature +77 -0
  8. data/features/deleting_instances.feature +67 -0
  9. data/features/direct_attributes.feature +11 -0
  10. data/features/excerpts.feature +13 -0
  11. data/features/extensible_delta_indexing.feature +9 -0
  12. data/features/facets.feature +90 -0
  13. data/features/facets_across_model.feature +29 -0
  14. data/features/handling_edits.feature +92 -0
  15. data/features/retry_stale_indexes.feature +24 -0
  16. data/features/searching_across_models.feature +20 -0
  17. data/features/searching_by_index.feature +40 -0
  18. data/features/searching_by_model.feature +175 -0
  19. data/features/searching_with_find_arguments.feature +56 -0
  20. data/features/sphinx_detection.feature +25 -0
  21. data/features/sphinx_scopes.feature +42 -0
  22. data/features/step_definitions/alpha_steps.rb +16 -0
  23. data/features/step_definitions/beta_steps.rb +7 -0
  24. data/features/step_definitions/common_steps.rb +193 -0
  25. data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
  26. data/features/step_definitions/facet_steps.rb +96 -0
  27. data/features/step_definitions/find_arguments_steps.rb +36 -0
  28. data/features/step_definitions/gamma_steps.rb +15 -0
  29. data/features/step_definitions/scope_steps.rb +15 -0
  30. data/features/step_definitions/search_steps.rb +89 -0
  31. data/features/step_definitions/sphinx_steps.rb +35 -0
  32. data/features/sti_searching.feature +19 -0
  33. data/features/support/env.rb +21 -0
  34. data/features/support/lib/generic_delta_handler.rb +8 -0
  35. data/features/thinking_sphinx/database.example.yml +3 -0
  36. data/features/thinking_sphinx/db/fixtures/alphas.rb +10 -0
  37. data/features/thinking_sphinx/db/fixtures/authors.rb +1 -0
  38. data/features/thinking_sphinx/db/fixtures/betas.rb +11 -0
  39. data/features/thinking_sphinx/db/fixtures/boxes.rb +9 -0
  40. data/features/thinking_sphinx/db/fixtures/categories.rb +1 -0
  41. data/features/thinking_sphinx/db/fixtures/cats.rb +3 -0
  42. data/features/thinking_sphinx/db/fixtures/comments.rb +24 -0
  43. data/features/thinking_sphinx/db/fixtures/developers.rb +31 -0
  44. data/features/thinking_sphinx/db/fixtures/dogs.rb +3 -0
  45. data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +10 -0
  46. data/features/thinking_sphinx/db/fixtures/foxes.rb +3 -0
  47. data/features/thinking_sphinx/db/fixtures/gammas.rb +10 -0
  48. data/features/thinking_sphinx/db/fixtures/music.rb +4 -0
  49. data/features/thinking_sphinx/db/fixtures/people.rb +1001 -0
  50. data/features/thinking_sphinx/db/fixtures/posts.rb +6 -0
  51. data/features/thinking_sphinx/db/fixtures/robots.rb +14 -0
  52. data/features/thinking_sphinx/db/fixtures/tags.rb +27 -0
  53. data/features/thinking_sphinx/db/migrations/create_alphas.rb +8 -0
  54. data/features/thinking_sphinx/db/migrations/create_animals.rb +5 -0
  55. data/features/thinking_sphinx/db/migrations/create_authors.rb +3 -0
  56. data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +6 -0
  57. data/features/thinking_sphinx/db/migrations/create_betas.rb +5 -0
  58. data/features/thinking_sphinx/db/migrations/create_boxes.rb +5 -0
  59. data/features/thinking_sphinx/db/migrations/create_categories.rb +3 -0
  60. data/features/thinking_sphinx/db/migrations/create_comments.rb +10 -0
  61. data/features/thinking_sphinx/db/migrations/create_developers.rb +7 -0
  62. data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +5 -0
  63. data/features/thinking_sphinx/db/migrations/create_gammas.rb +3 -0
  64. data/features/thinking_sphinx/db/migrations/create_genres.rb +3 -0
  65. data/features/thinking_sphinx/db/migrations/create_music.rb +6 -0
  66. data/features/thinking_sphinx/db/migrations/create_people.rb +13 -0
  67. data/features/thinking_sphinx/db/migrations/create_posts.rb +5 -0
  68. data/features/thinking_sphinx/db/migrations/create_robots.rb +4 -0
  69. data/features/thinking_sphinx/db/migrations/create_taggings.rb +5 -0
  70. data/features/thinking_sphinx/db/migrations/create_tags.rb +4 -0
  71. data/features/thinking_sphinx/models/alpha.rb +22 -0
  72. data/features/thinking_sphinx/models/animal.rb +5 -0
  73. data/features/thinking_sphinx/models/author.rb +3 -0
  74. data/features/thinking_sphinx/models/beta.rb +8 -0
  75. data/features/thinking_sphinx/models/box.rb +8 -0
  76. data/features/thinking_sphinx/models/cat.rb +3 -0
  77. data/features/thinking_sphinx/models/category.rb +4 -0
  78. data/features/thinking_sphinx/models/comment.rb +10 -0
  79. data/features/thinking_sphinx/models/developer.rb +16 -0
  80. data/features/thinking_sphinx/models/dog.rb +3 -0
  81. data/features/thinking_sphinx/models/extensible_beta.rb +9 -0
  82. data/features/thinking_sphinx/models/fox.rb +5 -0
  83. data/features/thinking_sphinx/models/gamma.rb +5 -0
  84. data/features/thinking_sphinx/models/genre.rb +3 -0
  85. data/features/thinking_sphinx/models/medium.rb +5 -0
  86. data/features/thinking_sphinx/models/music.rb +8 -0
  87. data/features/thinking_sphinx/models/person.rb +23 -0
  88. data/features/thinking_sphinx/models/post.rb +21 -0
  89. data/features/thinking_sphinx/models/robot.rb +12 -0
  90. data/features/thinking_sphinx/models/tag.rb +3 -0
  91. data/features/thinking_sphinx/models/tagging.rb +4 -0
  92. data/lib/cucumber/thinking_sphinx/external_world.rb +8 -0
  93. data/lib/cucumber/thinking_sphinx/internal_world.rb +127 -0
  94. data/lib/cucumber/thinking_sphinx/sql_logger.rb +20 -0
  95. data/lib/thinking_sphinx.rb +242 -0
  96. data/lib/thinking_sphinx/active_record.rb +380 -0
  97. data/lib/thinking_sphinx/active_record/attribute_updates.rb +50 -0
  98. data/lib/thinking_sphinx/active_record/delta.rb +61 -0
  99. data/lib/thinking_sphinx/active_record/has_many_association.rb +51 -0
  100. data/lib/thinking_sphinx/active_record/scopes.rb +75 -0
  101. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +47 -0
  102. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +58 -0
  103. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +147 -0
  104. data/lib/thinking_sphinx/association.rb +164 -0
  105. data/lib/thinking_sphinx/attribute.rb +380 -0
  106. data/lib/thinking_sphinx/auto_version.rb +22 -0
  107. data/lib/thinking_sphinx/class_facet.rb +15 -0
  108. data/lib/thinking_sphinx/configuration.rb +292 -0
  109. data/lib/thinking_sphinx/context.rb +74 -0
  110. data/lib/thinking_sphinx/core/array.rb +7 -0
  111. data/lib/thinking_sphinx/core/string.rb +15 -0
  112. data/lib/thinking_sphinx/deltas.rb +28 -0
  113. data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
  114. data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
  115. data/lib/thinking_sphinx/excerpter.rb +22 -0
  116. data/lib/thinking_sphinx/facet.rb +125 -0
  117. data/lib/thinking_sphinx/facet_search.rb +146 -0
  118. data/lib/thinking_sphinx/field.rb +80 -0
  119. data/lib/thinking_sphinx/index.rb +157 -0
  120. data/lib/thinking_sphinx/index/builder.rb +302 -0
  121. data/lib/thinking_sphinx/index/faux_column.rb +118 -0
  122. data/lib/thinking_sphinx/join.rb +37 -0
  123. data/lib/thinking_sphinx/property.rb +168 -0
  124. data/lib/thinking_sphinx/rails_additions.rb +150 -0
  125. data/lib/thinking_sphinx/search.rb +785 -0
  126. data/lib/thinking_sphinx/search_methods.rb +439 -0
  127. data/lib/thinking_sphinx/source.rb +164 -0
  128. data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
  129. data/lib/thinking_sphinx/source/sql.rb +130 -0
  130. data/lib/thinking_sphinx/tasks.rb +121 -0
  131. data/lib/thinking_sphinx/test.rb +55 -0
  132. data/rails/init.rb +16 -0
  133. data/spec/thinking_sphinx/active_record/delta_spec.rb +128 -0
  134. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +71 -0
  135. data/spec/thinking_sphinx/active_record/scopes_spec.rb +177 -0
  136. data/spec/thinking_sphinx/active_record_spec.rb +618 -0
  137. data/spec/thinking_sphinx/association_spec.rb +239 -0
  138. data/spec/thinking_sphinx/attribute_spec.rb +548 -0
  139. data/spec/thinking_sphinx/auto_version_spec.rb +39 -0
  140. data/spec/thinking_sphinx/configuration_spec.rb +271 -0
  141. data/spec/thinking_sphinx/context_spec.rb +126 -0
  142. data/spec/thinking_sphinx/core/array_spec.rb +9 -0
  143. data/spec/thinking_sphinx/core/string_spec.rb +9 -0
  144. data/spec/thinking_sphinx/excerpter_spec.rb +49 -0
  145. data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
  146. data/spec/thinking_sphinx/facet_spec.rb +333 -0
  147. data/spec/thinking_sphinx/field_spec.rb +113 -0
  148. data/spec/thinking_sphinx/index/builder_spec.rb +495 -0
  149. data/spec/thinking_sphinx/index/faux_column_spec.rb +36 -0
  150. data/spec/thinking_sphinx/index_spec.rb +183 -0
  151. data/spec/thinking_sphinx/rails_additions_spec.rb +203 -0
  152. data/spec/thinking_sphinx/search_methods_spec.rb +152 -0
  153. data/spec/thinking_sphinx/search_spec.rb +1206 -0
  154. data/spec/thinking_sphinx/source_spec.rb +243 -0
  155. data/spec/thinking_sphinx_spec.rb +204 -0
  156. data/tasks/distribution.rb +46 -0
  157. data/tasks/rails.rake +1 -0
  158. data/tasks/testing.rb +76 -0
  159. metadata +342 -0
@@ -0,0 +1,22 @@
1
+ module ThinkingSphinx
2
+ class AutoVersion
3
+ def self.detect
4
+ version = ThinkingSphinx::Configuration.instance.version
5
+ case version
6
+ when '0.9.8', '0.9.9'
7
+ require "riddle/#{version}"
8
+ else
9
+ STDERR.puts %Q{
10
+ Sphinx cannot be found on your system. You may need to configure the following
11
+ settings in your config/sphinx.yml file:
12
+ * bin_path
13
+ * searchd_binary_name
14
+ * indexer_binary_name
15
+
16
+ For more information, read the documentation:
17
+ http://freelancing-god.github.com/ts/en/advanced_config.html
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module ThinkingSphinx
2
+ class ClassFacet < ThinkingSphinx::Facet
3
+ def name
4
+ :class
5
+ end
6
+
7
+ def attribute_name
8
+ "class_crc"
9
+ end
10
+
11
+ def value(object, attribute_value)
12
+ object.class.name
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,292 @@
1
+ require 'erb'
2
+ require 'singleton'
3
+
4
+ module ThinkingSphinx
5
+ # This class both keeps track of the configuration settings for Sphinx and
6
+ # also generates the resulting file for Sphinx to use.
7
+ #
8
+ # Here are the default settings, relative to RAILS_ROOT where relevant:
9
+ #
10
+ # config file:: config/#{environment}.sphinx.conf
11
+ # searchd log file:: log/searchd.log
12
+ # query log file:: log/searchd.query.log
13
+ # pid file:: log/searchd.#{environment}.pid
14
+ # searchd files:: db/sphinx/#{environment}/
15
+ # address:: 127.0.0.1
16
+ # port:: 9312
17
+ # allow star:: false
18
+ # min prefix length:: 1
19
+ # min infix length:: 1
20
+ # mem limit:: 64M
21
+ # max matches:: 1000
22
+ # morphology:: nil
23
+ # charset type:: utf-8
24
+ # charset table:: nil
25
+ # ignore chars:: nil
26
+ # html strip:: false
27
+ # html remove elements:: ''
28
+ # searchd_binary_name:: searchd
29
+ # indexer_binary_name:: indexer
30
+ #
31
+ # If you want to change these settings, create a YAML file at
32
+ # config/sphinx.yml with settings for each environment, in a similar
33
+ # fashion to database.yml - using the following keys: config_file,
34
+ # searchd_log_file, query_log_file, pid_file, searchd_file_path, port,
35
+ # allow_star, enable_star, min_prefix_len, min_infix_len, mem_limit,
36
+ # max_matches, morphology, charset_type, charset_table, ignore_chars,
37
+ # html_strip, html_remove_elements, delayed_job_priority,
38
+ # searchd_binary_name, indexer_binary_name.
39
+ #
40
+ # I think you've got the idea.
41
+ #
42
+ # Each setting in the YAML file is optional - so only put in the ones you
43
+ # want to change.
44
+ #
45
+ # Keep in mind, if for some particular reason you're using a version of
46
+ # Sphinx older than 0.9.8 r871 (that's prior to the proper 0.9.8 release),
47
+ # don't set allow_star to true.
48
+ #
49
+ class Configuration
50
+ include Singleton
51
+
52
+ SourceOptions = %w( mysql_connect_flags mysql_ssl_cert mysql_ssl_key
53
+ mysql_ssl_ca sql_range_step sql_query_pre sql_query_post
54
+ sql_query_killlist sql_ranged_throttle sql_query_post_index unpack_zlib
55
+ unpack_mysqlcompress unpack_mysqlcompress_maxsize )
56
+
57
+ IndexOptions = %w( charset_table charset_type charset_dictpath docinfo
58
+ enable_star exceptions html_index_attrs html_remove_elements html_strip
59
+ index_exact_words ignore_chars inplace_docinfo_gap inplace_enable
60
+ inplace_hit_gap inplace_reloc_factor inplace_write_factor min_infix_len
61
+ min_prefix_len min_stemming_len min_word_len mlock morphology ngram_chars
62
+ ngram_len ondisk_dict overshort_step phrase_boundary phrase_boundary_step
63
+ preopen stopwords stopwords_step wordforms )
64
+
65
+ CustomOptions = %w( disable_range )
66
+
67
+ attr_accessor :searchd_file_path, :allow_star, :database_yml_file,
68
+ :app_root, :model_directories, :delayed_job_priority, :indexed_models
69
+
70
+ attr_accessor :source_options, :index_options
71
+ attr_accessor :version
72
+
73
+ attr_reader :environment, :configuration, :controller
74
+
75
+ # Load in the configuration settings - this will look for config/sphinx.yml
76
+ # and parse it according to the current environment.
77
+ #
78
+ def initialize(app_root = Dir.pwd)
79
+ self.reset
80
+ end
81
+
82
+ def self.configure(&block)
83
+ yield instance
84
+ instance.reset(instance.app_root)
85
+ end
86
+
87
+ def reset(custom_app_root=nil)
88
+ if custom_app_root
89
+ self.app_root = custom_app_root
90
+ else
91
+ self.app_root = RAILS_ROOT if defined?(RAILS_ROOT)
92
+ self.app_root = Merb.root if defined?(Merb)
93
+ self.app_root ||= app_root
94
+ end
95
+
96
+ @configuration = Riddle::Configuration.new
97
+ @configuration.searchd.pid_file = "#{self.app_root}/log/searchd.#{environment}.pid"
98
+ @configuration.searchd.log = "#{self.app_root}/log/searchd.log"
99
+ @configuration.searchd.query_log = "#{self.app_root}/log/searchd.query.log"
100
+
101
+ @controller = Riddle::Controller.new @configuration,
102
+ "#{self.app_root}/config/#{environment}.sphinx.conf"
103
+
104
+ self.address = "127.0.0.1"
105
+ self.port = 9312
106
+ self.database_yml_file = "#{self.app_root}/config/database.yml"
107
+ self.searchd_file_path = "#{self.app_root}/db/sphinx/#{environment}"
108
+ self.allow_star = false
109
+ self.model_directories = ["#{app_root}/app/models/"] +
110
+ Dir.glob("#{app_root}/vendor/plugins/*/app/models/")
111
+ self.delayed_job_priority = 0
112
+ self.indexed_models = []
113
+
114
+ self.source_options = {}
115
+ self.index_options = {
116
+ :charset_type => "utf-8"
117
+ }
118
+
119
+ self.version = nil
120
+ parse_config
121
+ self.version ||= @controller.sphinx_version
122
+
123
+ self
124
+ end
125
+
126
+ def self.environment
127
+ Thread.current[:thinking_sphinx_environment] ||= begin
128
+ if defined?(Merb)
129
+ Merb.environment
130
+ elsif defined?(RAILS_ENV)
131
+ RAILS_ENV
132
+ else
133
+ ENV['RAILS_ENV'] || 'development'
134
+ end
135
+ end
136
+ end
137
+
138
+ def environment
139
+ self.class.environment
140
+ end
141
+
142
+ # Generate the config file for Sphinx by using all the settings defined and
143
+ # looping through all the models with indexes to build the relevant
144
+ # indexer and searchd configuration, and sources and indexes details.
145
+ #
146
+ def build(file_path=nil)
147
+ file_path ||= "#{self.config_file}"
148
+
149
+ @configuration.indexes.clear
150
+
151
+ ThinkingSphinx.context.indexed_models.each do |model|
152
+ model = model.constantize
153
+ model.define_indexes
154
+ @configuration.indexes.concat model.to_riddle
155
+ end
156
+
157
+ open(file_path, "w") do |file|
158
+ file.write @configuration.render
159
+ end
160
+ end
161
+
162
+ def address
163
+ @address
164
+ end
165
+
166
+ def address=(address)
167
+ @address = address
168
+ @configuration.searchd.address = address
169
+ end
170
+
171
+ def port
172
+ @port
173
+ end
174
+
175
+ def port=(port)
176
+ @port = port
177
+ @configuration.searchd.port = port
178
+ end
179
+
180
+ def pid_file
181
+ @configuration.searchd.pid_file
182
+ end
183
+
184
+ def pid_file=(pid_file)
185
+ @configuration.searchd.pid_file = pid_file
186
+ end
187
+
188
+ def searchd_log_file
189
+ @configuration.searchd.log
190
+ end
191
+
192
+ def searchd_log_file=(file)
193
+ @configuration.searchd.log = file
194
+ end
195
+
196
+ def query_log_file
197
+ @configuration.searchd.query_log
198
+ end
199
+
200
+ def query_log_file=(file)
201
+ @configuration.searchd.query_log = file
202
+ end
203
+
204
+ def config_file
205
+ @controller.path
206
+ end
207
+
208
+ def config_file=(file)
209
+ @controller.path = file
210
+ end
211
+
212
+ def bin_path
213
+ @controller.bin_path
214
+ end
215
+
216
+ def bin_path=(path)
217
+ @controller.bin_path = path
218
+ end
219
+
220
+ def searchd_binary_name
221
+ @controller.searchd_binary_name
222
+ end
223
+
224
+ def searchd_binary_name=(name)
225
+ @controller.searchd_binary_name = name
226
+ end
227
+
228
+ def indexer_binary_name
229
+ @controller.indexer_binary_name
230
+ end
231
+
232
+ def indexer_binary_name=(name)
233
+ @controller.indexer_binary_name = name
234
+ end
235
+
236
+ def client
237
+ client = Riddle::Client.new address, port
238
+ client.max_matches = configuration.searchd.max_matches || 1000
239
+ client
240
+ end
241
+
242
+ def models_by_crc
243
+ @models_by_crc ||= begin
244
+ ThinkingSphinx.context.indexed_models.inject({}) do |hash, model|
245
+ hash[model.constantize.to_crc32] = model
246
+ Object.subclasses_of(model.constantize).each { |subclass|
247
+ hash[subclass.to_crc32] = subclass.name
248
+ }
249
+ hash
250
+ end
251
+ end
252
+ end
253
+
254
+ private
255
+
256
+ # Parse the config/sphinx.yml file - if it exists - then use the attribute
257
+ # accessors to set the appropriate values. Nothing too clever.
258
+ #
259
+ def parse_config
260
+ path = "#{app_root}/config/sphinx.yml"
261
+ return unless File.exists?(path)
262
+
263
+ conf = YAML::load(ERB.new(IO.read(path)).result)[environment]
264
+
265
+ conf.each do |key,value|
266
+ self.send("#{key}=", value) if self.respond_to?("#{key}=")
267
+
268
+ set_sphinx_setting self.source_options, key, value, SourceOptions
269
+ set_sphinx_setting self.index_options, key, value, IndexOptions
270
+ set_sphinx_setting self.index_options, key, value, CustomOptions
271
+ set_sphinx_setting @configuration.searchd, key, value
272
+ set_sphinx_setting @configuration.indexer, key, value
273
+ end unless conf.nil?
274
+
275
+ self.bin_path += '/' unless self.bin_path.blank?
276
+
277
+ if self.allow_star
278
+ self.index_options[:enable_star] = true
279
+ self.index_options[:min_prefix_len] = 1
280
+ end
281
+ end
282
+
283
+ def set_sphinx_setting(object, key, value, allowed = {})
284
+ if object.is_a?(Hash)
285
+ object[key.to_sym] = value if allowed.include?(key.to_s)
286
+ else
287
+ object.send("#{key}=", value) if object.respond_to?("#{key}")
288
+ send("#{key}=", value) if self.respond_to?("#{key}")
289
+ end
290
+ end
291
+ end
292
+ end
@@ -0,0 +1,74 @@
1
+ class ThinkingSphinx::Context
2
+ attr_reader :indexed_models
3
+
4
+ def initialize(*models)
5
+ @indexed_models = []
6
+ end
7
+
8
+ def prepare
9
+ ThinkingSphinx::Configuration.instance.indexed_models.each do |model|
10
+ add_indexed_model model
11
+ end
12
+
13
+ return unless indexed_models.empty?
14
+
15
+ load_models
16
+ add_indexed_models
17
+ end
18
+
19
+ def define_indexes
20
+ indexed_models.each { |model|
21
+ model.constantize.define_indexes
22
+ }
23
+ end
24
+
25
+ def add_indexed_model(model)
26
+ model = model.name if model.is_a?(Class)
27
+
28
+ indexed_models << model
29
+ indexed_models.uniq!
30
+ indexed_models.sort!
31
+ end
32
+
33
+ def superclass_indexed_models
34
+ klasses = indexed_models.collect { |name| name.constantize }
35
+ klasses.reject { |klass|
36
+ klass.superclass.ancestors.any? { |ancestor| klasses.include?(ancestor) }
37
+ }.collect { |klass| klass.name }
38
+ end
39
+
40
+ private
41
+
42
+ def add_indexed_models
43
+ Object.subclasses_of(ActiveRecord::Base).each do |klass|
44
+ add_indexed_model klass if klass.has_sphinx_indexes?
45
+ end
46
+ end
47
+
48
+ # Make sure all models are loaded - without reloading any that
49
+ # ActiveRecord::Base is already aware of (otherwise we start to hit some
50
+ # messy dependencies issues).
51
+ #
52
+ def load_models
53
+ ThinkingSphinx::Configuration.instance.model_directories.each do |base|
54
+ Dir["#{base}**/*.rb"].each do |file|
55
+ model_name = file.gsub(/^#{base}([\w_\/\\]+)\.rb/, '\1')
56
+
57
+ next if model_name.nil?
58
+ next if ::ActiveRecord::Base.send(:subclasses).detect { |model|
59
+ model.name == model_name.camelize
60
+ }
61
+
62
+ begin
63
+ model_name.camelize.constantize
64
+ rescue LoadError
65
+ model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
66
+ rescue NameError
67
+ next
68
+ rescue StandardError
69
+ STDERR.puts "Warning: Error loading #{file}"
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,7 @@
1
+ module SearchAsArray
2
+ def ===(object)
3
+ object.is_a?(ThinkingSphinx::Search) || super
4
+ end
5
+ end
6
+
7
+ Array.extend SearchAsArray
@@ -0,0 +1,15 @@
1
+ require 'zlib'
2
+
3
+ module ThinkingSphinx
4
+ module Core
5
+ module String
6
+ def to_crc32
7
+ Zlib.crc32 self
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ class String
14
+ include ThinkingSphinx::Core::String
15
+ end
@@ -0,0 +1,28 @@
1
+ require 'thinking_sphinx/deltas/default_delta'
2
+
3
+ module ThinkingSphinx
4
+ module Deltas
5
+ def self.parse(index)
6
+ delta_option = index.local_options.delete(:delta)
7
+ case delta_option
8
+ when TrueClass, :default
9
+ DefaultDelta.new index, index.local_options
10
+ when :delayed
11
+ DelayedDelta.new index, index.local_options
12
+ when :datetime
13
+ DatetimeDelta.new index, index.local_options
14
+ when FalseClass, nil
15
+ nil
16
+ else
17
+ if delta_option.is_a?(String)
18
+ delta_option = Kernel.const_get(delta_option)
19
+ end
20
+ if delta_option.ancestors.include?(ThinkingSphinx::Deltas::DefaultDelta)
21
+ delta_option.new index, index.local_options
22
+ else
23
+ raise "Unknown delta type"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end