thinking-sphinx 3.1.4 → 6.0.0

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 (347) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +99 -0
  3. data/.github/actions/test/action.yml +46 -0
  4. data/.github/workflows/ci.yml +75 -0
  5. data/.gitignore +7 -2
  6. data/.travis.yml +31 -16
  7. data/Appraisals +68 -12
  8. data/CHANGELOG.markdown +782 -0
  9. data/Gemfile +13 -4
  10. data/Procfile.support +2 -0
  11. data/README.textile +41 -27
  12. data/Rakefile +2 -0
  13. data/bin/console +15 -0
  14. data/bin/loadsphinx +99 -0
  15. data/bin/testmatrix +48 -0
  16. data/lib/thinking/sphinx.rb +2 -0
  17. data/lib/thinking-sphinx.rb +2 -0
  18. data/lib/thinking_sphinx/active_record/association.rb +2 -0
  19. data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +3 -1
  20. data/lib/thinking_sphinx/active_record/association_proxy/attribute_matcher.rb +2 -0
  21. data/lib/thinking_sphinx/active_record/association_proxy.rb +3 -2
  22. data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +3 -1
  23. data/lib/thinking_sphinx/active_record/attribute/type.rb +20 -4
  24. data/lib/thinking_sphinx/active_record/attribute/values.rb +2 -0
  25. data/lib/thinking_sphinx/active_record/attribute.rb +2 -0
  26. data/lib/thinking_sphinx/active_record/base.rb +43 -11
  27. data/lib/thinking_sphinx/active_record/callbacks/association_delta_callbacks.rb +21 -0
  28. data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +15 -9
  29. data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +20 -5
  30. data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +18 -4
  31. data/lib/thinking_sphinx/active_record/column.rb +2 -0
  32. data/lib/thinking_sphinx/active_record/column_sql_presenter.rb +7 -1
  33. data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +2 -0
  34. data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +9 -1
  35. data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +2 -0
  36. data/lib/thinking_sphinx/active_record/database_adapters.rb +3 -1
  37. data/lib/thinking_sphinx/active_record/depolymorph/association_reflection.rb +32 -0
  38. data/lib/thinking_sphinx/active_record/depolymorph/base_reflection.rb +32 -0
  39. data/lib/thinking_sphinx/active_record/depolymorph/conditions_reflection.rb +40 -0
  40. data/lib/thinking_sphinx/active_record/depolymorph/overridden_reflection.rb +50 -0
  41. data/lib/thinking_sphinx/active_record/depolymorph/scoped_reflection.rb +26 -0
  42. data/lib/thinking_sphinx/active_record/field.rb +2 -0
  43. data/lib/thinking_sphinx/active_record/filter_reflection.rb +13 -71
  44. data/lib/thinking_sphinx/active_record/index.rb +7 -5
  45. data/lib/thinking_sphinx/active_record/interpreter.rb +6 -4
  46. data/lib/thinking_sphinx/active_record/join_association.rb +5 -1
  47. data/lib/thinking_sphinx/active_record/log_subscriber.rb +22 -3
  48. data/lib/thinking_sphinx/active_record/polymorpher.rb +2 -0
  49. data/lib/thinking_sphinx/active_record/property.rb +2 -0
  50. data/lib/thinking_sphinx/active_record/property_query.rb +4 -1
  51. data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +2 -0
  52. data/lib/thinking_sphinx/active_record/simple_many_query.rb +2 -0
  53. data/lib/thinking_sphinx/active_record/source_joins.rb +68 -0
  54. data/lib/thinking_sphinx/active_record/sql_builder/clause_builder.rb +2 -0
  55. data/lib/thinking_sphinx/active_record/sql_builder/query.rb +13 -0
  56. data/lib/thinking_sphinx/active_record/sql_builder/statement.rb +2 -0
  57. data/lib/thinking_sphinx/active_record/sql_builder.rb +5 -18
  58. data/lib/thinking_sphinx/active_record/sql_source/template.rb +5 -3
  59. data/lib/thinking_sphinx/active_record/sql_source.rb +35 -9
  60. data/lib/thinking_sphinx/active_record.rb +14 -1
  61. data/lib/thinking_sphinx/attribute_types.rb +72 -0
  62. data/lib/thinking_sphinx/batched_search.rb +2 -0
  63. data/lib/thinking_sphinx/callbacks/appender.rb +63 -0
  64. data/lib/thinking_sphinx/callbacks.rb +29 -0
  65. data/lib/thinking_sphinx/capistrano/v2.rb +2 -0
  66. data/lib/thinking_sphinx/capistrano/v3.rb +2 -0
  67. data/lib/thinking_sphinx/capistrano.rb +2 -0
  68. data/lib/thinking_sphinx/commander.rb +27 -0
  69. data/lib/thinking_sphinx/commands/base.rb +53 -0
  70. data/lib/thinking_sphinx/commands/clear_real_time.rb +22 -0
  71. data/lib/thinking_sphinx/commands/clear_sql.rb +18 -0
  72. data/lib/thinking_sphinx/commands/configure.rb +15 -0
  73. data/lib/thinking_sphinx/commands/index_real_time.rb +15 -0
  74. data/lib/thinking_sphinx/commands/index_sql.rb +25 -0
  75. data/lib/thinking_sphinx/commands/merge.rb +27 -0
  76. data/lib/thinking_sphinx/commands/merge_and_update.rb +57 -0
  77. data/lib/thinking_sphinx/commands/prepare.rb +15 -0
  78. data/lib/thinking_sphinx/commands/rotate.rb +13 -0
  79. data/lib/thinking_sphinx/commands/running.rb +15 -0
  80. data/lib/thinking_sphinx/commands/start_attached.rb +22 -0
  81. data/lib/thinking_sphinx/commands/start_detached.rb +21 -0
  82. data/lib/thinking_sphinx/commands/stop.rb +24 -0
  83. data/lib/thinking_sphinx/commands.rb +20 -0
  84. data/lib/thinking_sphinx/configuration/consistent_ids.rb +2 -0
  85. data/lib/thinking_sphinx/configuration/defaults.rb +2 -0
  86. data/lib/thinking_sphinx/configuration/distributed_indices.rb +3 -1
  87. data/lib/thinking_sphinx/configuration/duplicate_names.rb +36 -0
  88. data/lib/thinking_sphinx/configuration/minimum_fields.rb +17 -12
  89. data/lib/thinking_sphinx/configuration.rb +90 -74
  90. data/lib/thinking_sphinx/connection/client.rb +74 -0
  91. data/lib/thinking_sphinx/connection/jruby.rb +58 -0
  92. data/lib/thinking_sphinx/connection/mri.rb +26 -0
  93. data/lib/thinking_sphinx/connection.rb +13 -114
  94. data/lib/thinking_sphinx/core/field.rb +2 -0
  95. data/lib/thinking_sphinx/core/index.rb +22 -2
  96. data/lib/thinking_sphinx/core/interpreter.rb +2 -0
  97. data/lib/thinking_sphinx/core/property.rb +2 -0
  98. data/lib/thinking_sphinx/core/settings.rb +2 -0
  99. data/lib/thinking_sphinx/core.rb +2 -0
  100. data/lib/thinking_sphinx/deletion.rb +33 -13
  101. data/lib/thinking_sphinx/deltas/default_delta.rb +3 -1
  102. data/lib/thinking_sphinx/deltas/delete_job.rb +16 -4
  103. data/lib/thinking_sphinx/deltas/index_job.rb +14 -2
  104. data/lib/thinking_sphinx/deltas.rb +2 -0
  105. data/lib/thinking_sphinx/distributed/index.rb +25 -3
  106. data/lib/thinking_sphinx/distributed.rb +2 -0
  107. data/lib/thinking_sphinx/errors.rb +47 -3
  108. data/lib/thinking_sphinx/excerpter.rb +2 -0
  109. data/lib/thinking_sphinx/facet.rb +4 -3
  110. data/lib/thinking_sphinx/facet_search.rb +4 -2
  111. data/lib/thinking_sphinx/float_formatter.rb +2 -0
  112. data/lib/thinking_sphinx/frameworks/plain.rb +2 -0
  113. data/lib/thinking_sphinx/frameworks/rails.rb +2 -0
  114. data/lib/thinking_sphinx/frameworks.rb +2 -0
  115. data/lib/thinking_sphinx/guard/file.rb +3 -1
  116. data/lib/thinking_sphinx/guard/files.rb +2 -0
  117. data/lib/thinking_sphinx/guard/none.rb +7 -0
  118. data/lib/thinking_sphinx/guard.rb +3 -0
  119. data/lib/thinking_sphinx/hooks/guard_presence.rb +34 -0
  120. data/lib/thinking_sphinx/index.rb +2 -0
  121. data/lib/thinking_sphinx/index_set.rb +27 -4
  122. data/lib/thinking_sphinx/indexing_strategies/all_at_once.rb +9 -0
  123. data/lib/thinking_sphinx/indexing_strategies/one_at_a_time.rb +16 -0
  124. data/lib/thinking_sphinx/interfaces/base.rb +13 -0
  125. data/lib/thinking_sphinx/interfaces/daemon.rb +27 -0
  126. data/lib/thinking_sphinx/interfaces/real_time.rb +46 -0
  127. data/lib/thinking_sphinx/interfaces/sql.rb +53 -0
  128. data/lib/thinking_sphinx/interfaces.rb +10 -0
  129. data/lib/thinking_sphinx/logger.rb +2 -0
  130. data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +6 -4
  131. data/lib/thinking_sphinx/masks/pagination_mask.rb +2 -0
  132. data/lib/thinking_sphinx/masks/scopes_mask.rb +8 -0
  133. data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +3 -1
  134. data/lib/thinking_sphinx/masks.rb +2 -0
  135. data/lib/thinking_sphinx/middlewares/active_record_translator.rb +32 -9
  136. data/lib/thinking_sphinx/middlewares/geographer.rb +2 -0
  137. data/lib/thinking_sphinx/middlewares/glazier.rb +14 -1
  138. data/lib/thinking_sphinx/middlewares/ids_only.rb +2 -0
  139. data/lib/thinking_sphinx/middlewares/inquirer.rb +3 -1
  140. data/lib/thinking_sphinx/middlewares/middleware.rb +2 -0
  141. data/lib/thinking_sphinx/middlewares/sphinxql.rb +18 -16
  142. data/lib/thinking_sphinx/middlewares/stale_id_checker.rb +3 -1
  143. data/lib/thinking_sphinx/middlewares/stale_id_filter.rb +4 -2
  144. data/lib/thinking_sphinx/middlewares/valid_options.rb +25 -0
  145. data/lib/thinking_sphinx/middlewares.rb +7 -3
  146. data/lib/thinking_sphinx/panes/attributes_pane.rb +2 -0
  147. data/lib/thinking_sphinx/panes/distance_pane.rb +2 -0
  148. data/lib/thinking_sphinx/panes/excerpts_pane.rb +2 -0
  149. data/lib/thinking_sphinx/panes/weight_pane.rb +3 -1
  150. data/lib/thinking_sphinx/panes.rb +2 -0
  151. data/lib/thinking_sphinx/processor.rb +71 -0
  152. data/lib/thinking_sphinx/query.rb +2 -0
  153. data/lib/thinking_sphinx/railtie.rb +29 -2
  154. data/lib/thinking_sphinx/rake_interface.rb +14 -69
  155. data/lib/thinking_sphinx/real_time/attribute.rb +9 -1
  156. data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +17 -7
  157. data/lib/thinking_sphinx/real_time/field.rb +2 -0
  158. data/lib/thinking_sphinx/real_time/index/template.rb +19 -1
  159. data/lib/thinking_sphinx/real_time/index.rb +11 -5
  160. data/lib/thinking_sphinx/real_time/interpreter.rb +10 -6
  161. data/lib/thinking_sphinx/real_time/populator.rb +12 -14
  162. data/lib/thinking_sphinx/real_time/processor.rb +36 -0
  163. data/lib/thinking_sphinx/real_time/property.rb +3 -5
  164. data/lib/thinking_sphinx/real_time/transcribe_instance.rb +38 -0
  165. data/lib/thinking_sphinx/real_time/transcriber.rb +63 -15
  166. data/lib/thinking_sphinx/real_time/translator.rb +39 -0
  167. data/lib/thinking_sphinx/real_time.rb +22 -1
  168. data/lib/thinking_sphinx/scopes.rb +6 -0
  169. data/lib/thinking_sphinx/search/batch_inquirer.rb +2 -0
  170. data/lib/thinking_sphinx/search/context.rb +11 -0
  171. data/lib/thinking_sphinx/search/glaze.rb +2 -0
  172. data/lib/thinking_sphinx/search/merger.rb +2 -0
  173. data/lib/thinking_sphinx/search/query.rb +9 -1
  174. data/lib/thinking_sphinx/search/stale_ids_exception.rb +7 -3
  175. data/lib/thinking_sphinx/search.rb +30 -2
  176. data/lib/thinking_sphinx/settings.rb +128 -0
  177. data/lib/thinking_sphinx/sinatra.rb +3 -1
  178. data/lib/thinking_sphinx/subscribers/populator_subscriber.rb +19 -5
  179. data/lib/thinking_sphinx/tasks.rb +55 -28
  180. data/lib/thinking_sphinx/test.rb +3 -1
  181. data/lib/thinking_sphinx/utf8.rb +2 -0
  182. data/lib/thinking_sphinx/wildcard.rb +3 -1
  183. data/lib/thinking_sphinx/with_output.rb +13 -0
  184. data/lib/thinking_sphinx.rb +35 -4
  185. data/spec/acceptance/association_scoping_spec.rb +7 -5
  186. data/spec/acceptance/attribute_access_spec.rb +29 -12
  187. data/spec/acceptance/attribute_updates_spec.rb +5 -3
  188. data/spec/acceptance/batch_searching_spec.rb +6 -4
  189. data/spec/acceptance/big_integers_spec.rb +9 -7
  190. data/spec/acceptance/excerpts_spec.rb +11 -10
  191. data/spec/acceptance/facets_spec.rb +29 -16
  192. data/spec/acceptance/geosearching_spec.rb +22 -10
  193. data/spec/acceptance/grouping_by_attributes_spec.rb +30 -28
  194. data/spec/acceptance/index_options_spec.rb +18 -16
  195. data/spec/acceptance/indexing_spec.rb +5 -3
  196. data/spec/acceptance/merging_spec.rb +90 -0
  197. data/spec/acceptance/paginating_search_results_spec.rb +21 -3
  198. data/spec/acceptance/real_time_updates_spec.rb +103 -5
  199. data/spec/acceptance/remove_deleted_records_spec.rb +64 -8
  200. data/spec/acceptance/search_counts_spec.rb +4 -2
  201. data/spec/acceptance/search_for_just_ids_spec.rb +4 -2
  202. data/spec/acceptance/searching_across_models_spec.rb +15 -6
  203. data/spec/acceptance/searching_across_schemas_spec.rb +12 -10
  204. data/spec/acceptance/searching_on_fields_spec.rb +11 -9
  205. data/spec/acceptance/searching_with_filters_spec.rb +35 -20
  206. data/spec/acceptance/searching_with_sti_spec.rb +11 -9
  207. data/spec/acceptance/searching_within_a_model_spec.rb +44 -17
  208. data/spec/acceptance/sorting_search_results_spec.rb +21 -19
  209. data/spec/acceptance/spec_helper.rb +2 -13
  210. data/spec/acceptance/specifying_sql_spec.rb +118 -62
  211. data/spec/acceptance/sphinx_scopes_spec.rb +30 -21
  212. data/spec/acceptance/sql_deltas_spec.rb +35 -9
  213. data/spec/acceptance/support/database_cleaner.rb +3 -1
  214. data/spec/acceptance/support/sphinx_controller.rb +25 -9
  215. data/spec/acceptance/support/sphinx_helpers.rb +17 -2
  216. data/spec/acceptance/suspended_deltas_spec.rb +14 -12
  217. data/spec/fixtures/database.yml +1 -1
  218. data/spec/internal/app/indices/admin_person_index.rb +6 -0
  219. data/spec/internal/app/indices/album_index.rb +9 -0
  220. data/spec/internal/app/indices/animal_index.rb +2 -0
  221. data/spec/internal/app/indices/article_index.rb +10 -3
  222. data/spec/internal/app/indices/bird_index.rb +2 -0
  223. data/spec/internal/app/indices/book_index.rb +4 -1
  224. data/spec/internal/app/indices/car_index.rb +2 -0
  225. data/spec/internal/app/indices/city_index.rb +2 -0
  226. data/spec/internal/app/indices/colour_index.rb +7 -0
  227. data/spec/internal/app/indices/product_index.rb +3 -2
  228. data/spec/internal/app/indices/tee_index.rb +3 -1
  229. data/spec/internal/app/indices/user_index.rb +2 -0
  230. data/spec/internal/app/models/admin/person.rb +6 -0
  231. data/spec/internal/app/models/album.rb +25 -0
  232. data/spec/internal/app/models/animal.rb +3 -0
  233. data/spec/internal/app/models/article.rb +4 -0
  234. data/spec/internal/app/models/bird.rb +3 -0
  235. data/spec/internal/app/models/book.rb +9 -5
  236. data/spec/internal/app/models/car.rb +3 -1
  237. data/spec/internal/app/models/categorisation.rb +10 -1
  238. data/spec/internal/app/models/category.rb +2 -0
  239. data/spec/internal/app/models/city.rb +4 -0
  240. data/spec/internal/app/models/colour.rb +4 -0
  241. data/spec/internal/app/models/event.rb +2 -0
  242. data/spec/internal/app/models/flightless_bird.rb +2 -0
  243. data/spec/internal/app/models/genre.rb +2 -0
  244. data/spec/internal/app/models/hardcover.rb +2 -0
  245. data/spec/internal/app/models/mammal.rb +2 -0
  246. data/spec/internal/app/models/manufacturer.rb +2 -0
  247. data/spec/internal/app/models/product.rb +3 -1
  248. data/spec/internal/app/models/tag.rb +2 -0
  249. data/spec/internal/app/models/tagging.rb +2 -0
  250. data/spec/internal/app/models/tee.rb +7 -0
  251. data/spec/internal/app/models/tweet.rb +2 -0
  252. data/spec/internal/app/models/user.rb +4 -0
  253. data/spec/internal/config/database.yml +12 -1
  254. data/spec/internal/db/schema.rb +13 -1
  255. data/spec/spec_helper.rb +12 -1
  256. data/spec/support/json_column.rb +35 -0
  257. data/spec/support/multi_schema.rb +5 -1
  258. data/spec/support/mysql.rb +25 -0
  259. data/spec/support/sphinx_yaml_helpers.rb +8 -1
  260. data/spec/thinking_sphinx/active_record/association_spec.rb +3 -1
  261. data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +43 -38
  262. data/spec/thinking_sphinx/active_record/base_spec.rb +31 -29
  263. data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +81 -10
  264. data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +56 -29
  265. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +27 -10
  266. data/spec/thinking_sphinx/active_record/column_spec.rb +15 -13
  267. data/spec/thinking_sphinx/active_record/column_sql_presenter_spec.rb +39 -0
  268. data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +7 -5
  269. data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +26 -12
  270. data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +15 -13
  271. data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +50 -48
  272. data/spec/thinking_sphinx/active_record/field_spec.rb +9 -7
  273. data/spec/thinking_sphinx/active_record/filter_reflection_spec.rb +113 -80
  274. data/spec/thinking_sphinx/active_record/index_spec.rb +41 -37
  275. data/spec/thinking_sphinx/active_record/interpreter_spec.rb +62 -59
  276. data/spec/thinking_sphinx/active_record/polymorpher_spec.rb +16 -14
  277. data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +69 -67
  278. data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +146 -154
  279. data/spec/thinking_sphinx/active_record/sql_source_spec.rb +185 -109
  280. data/spec/thinking_sphinx/attribute_types_spec.rb +52 -0
  281. data/spec/thinking_sphinx/commands/clear_real_time_spec.rb +46 -0
  282. data/spec/thinking_sphinx/commands/clear_sql_spec.rb +52 -0
  283. data/spec/thinking_sphinx/commands/configure_spec.rb +31 -0
  284. data/spec/thinking_sphinx/commands/index_real_time_spec.rb +33 -0
  285. data/spec/thinking_sphinx/commands/index_sql_spec.rb +86 -0
  286. data/spec/thinking_sphinx/commands/merge_and_update_spec.rb +106 -0
  287. data/spec/thinking_sphinx/commands/merge_spec.rb +48 -0
  288. data/spec/thinking_sphinx/commands/prepare_spec.rb +31 -0
  289. data/spec/thinking_sphinx/commands/running_spec.rb +30 -0
  290. data/spec/thinking_sphinx/commands/start_detached_spec.rb +67 -0
  291. data/spec/thinking_sphinx/commands/stop_spec.rb +63 -0
  292. data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +60 -0
  293. data/spec/thinking_sphinx/configuration_spec.rb +247 -94
  294. data/spec/thinking_sphinx/connection/mri_spec.rb +49 -0
  295. data/spec/thinking_sphinx/connection_spec.rb +15 -13
  296. data/spec/thinking_sphinx/deletion_spec.rb +17 -17
  297. data/spec/thinking_sphinx/deltas/default_delta_spec.rb +28 -21
  298. data/spec/thinking_sphinx/deltas_spec.rb +14 -12
  299. data/spec/thinking_sphinx/errors_spec.rb +59 -27
  300. data/spec/thinking_sphinx/excerpter_spec.rb +12 -9
  301. data/spec/thinking_sphinx/facet_search_spec.rb +24 -22
  302. data/spec/thinking_sphinx/hooks/guard_presence_spec.rb +30 -0
  303. data/spec/thinking_sphinx/index_set_spec.rb +59 -18
  304. data/spec/thinking_sphinx/index_spec.rb +28 -26
  305. data/spec/thinking_sphinx/interfaces/daemon_spec.rb +60 -0
  306. data/spec/thinking_sphinx/interfaces/real_time_spec.rb +109 -0
  307. data/spec/thinking_sphinx/interfaces/sql_spec.rb +122 -0
  308. data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +22 -20
  309. data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +20 -18
  310. data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +45 -21
  311. data/spec/thinking_sphinx/middlewares/geographer_spec.rb +11 -9
  312. data/spec/thinking_sphinx/middlewares/glazier_spec.rb +12 -9
  313. data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +9 -7
  314. data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +60 -58
  315. data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +7 -4
  316. data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +39 -17
  317. data/spec/thinking_sphinx/middlewares/valid_options_spec.rb +51 -0
  318. data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +3 -1
  319. data/spec/thinking_sphinx/panes/distance_pane_spec.rb +6 -4
  320. data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +8 -6
  321. data/spec/thinking_sphinx/panes/weight_pane_spec.rb +4 -2
  322. data/spec/thinking_sphinx/rake_interface_spec.rb +17 -235
  323. data/spec/thinking_sphinx/real_time/attribute_spec.rb +15 -13
  324. data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +114 -28
  325. data/spec/thinking_sphinx/real_time/field_spec.rb +16 -14
  326. data/spec/thinking_sphinx/real_time/index_spec.rb +83 -32
  327. data/spec/thinking_sphinx/real_time/interpreter_spec.rb +44 -42
  328. data/spec/thinking_sphinx/real_time/transcribe_instance_spec.rb +35 -0
  329. data/spec/thinking_sphinx/real_time/transcriber_spec.rb +109 -0
  330. data/spec/thinking_sphinx/real_time/translator_spec.rb +17 -0
  331. data/spec/thinking_sphinx/scopes_spec.rb +11 -5
  332. data/spec/thinking_sphinx/search/glaze_spec.rb +17 -15
  333. data/spec/thinking_sphinx/search/query_spec.rb +19 -10
  334. data/spec/thinking_sphinx/search_spec.rb +30 -28
  335. data/spec/thinking_sphinx/wildcard_spec.rb +18 -11
  336. data/spec/thinking_sphinx_spec.rb +10 -7
  337. data/thinking-sphinx.gemspec +17 -10
  338. metadata +157 -49
  339. data/HISTORY +0 -248
  340. data/gemfiles/.gitignore +0 -1
  341. data/gemfiles/rails_3_2.gemfile +0 -11
  342. data/gemfiles/rails_4_0.gemfile +0 -11
  343. data/gemfiles/rails_4_1.gemfile +0 -11
  344. data/gemfiles/rails_4_2.gemfile +0 -11
  345. data/lib/thinking_sphinx/controller.rb +0 -10
  346. data/lib/thinking_sphinx/middlewares/utf8.rb +0 -27
  347. data/lib/thinking_sphinx/sphinxql.rb +0 -23
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Frameworks::Rails
2
4
  def environment
3
5
  Rails.env
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ThinkingSphinx::Frameworks
2
4
  def self.current
3
5
  defined?(::Rails) ? ThinkingSphinx::Frameworks::Rails.new :
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Guard::File
2
4
  attr_reader :name
3
5
 
@@ -10,7 +12,7 @@ class ThinkingSphinx::Guard::File
10
12
  end
11
13
 
12
14
  def locked?
13
- File.exists? path
15
+ File.exist? path
14
16
  end
15
17
 
16
18
  def path
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Guard::Files
2
4
  def self.call(names, &block)
3
5
  new(names).call(&block)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Guard::None
4
+ def self.call(names, &block)
5
+ block.call names
6
+ end
7
+ end
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ThinkingSphinx::Guard
2
4
  #
3
5
  end
4
6
 
5
7
  require 'thinking_sphinx/guard/file'
6
8
  require 'thinking_sphinx/guard/files'
9
+ require 'thinking_sphinx/guard/none'
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Hooks::GuardPresence
4
+ def self.call(configuration = nil, stream = STDERR)
5
+ new(configuration, stream).call
6
+ end
7
+
8
+ def initialize(configuration = nil, stream = STDERR)
9
+ @configuration = configuration || ThinkingSphinx::Configuration.instance
10
+ @stream = stream
11
+ end
12
+
13
+ def call
14
+ return if files.empty?
15
+
16
+ stream.puts "WARNING: The following indexing guard files exist:"
17
+ files.each do |file|
18
+ stream.puts " * #{file}"
19
+ end
20
+ stream.puts <<-TXT
21
+ These files indicate indexing is already happening. If that is not the case,
22
+ these files should be deleted to ensure all indices can be processed.
23
+
24
+ TXT
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :configuration, :stream
30
+
31
+ def files
32
+ @files ||= Dir["#{configuration.indices_location}/ts-*.tmp"]
33
+ end
34
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Index
2
4
  attr_reader :reference, :options, :block
3
5
 
@@ -1,6 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::IndexSet
2
4
  include Enumerable
3
5
 
6
+ def self.reference_name(klass)
7
+ @cached_results ||= {}
8
+ @cached_results[klass.name] ||= klass.name.underscore.to_sym
9
+ end
10
+
4
11
  delegate :each, :empty?, :to => :indices
5
12
 
6
13
  def initialize(options = {}, configuration = nil)
@@ -27,15 +34,15 @@ class ThinkingSphinx::IndexSet
27
34
  end
28
35
 
29
36
  def classes
30
- options[:classes] || []
37
+ options[:classes] || instances.collect(&:class)
31
38
  end
32
39
 
33
40
  def classes_specified?
34
- classes.any? || references_specified?
41
+ instances.any? || classes.any? || references_specified?
35
42
  end
36
43
 
37
44
  def classes_and_ancestors
38
- @classes_and_ancestors ||= classes.collect { |model|
45
+ @classes_and_ancestors ||= mti_classes + sti_classes.collect { |model|
39
46
  model.ancestors.take_while { |klass|
40
47
  klass != ActiveRecord::Base
41
48
  }.select { |klass|
@@ -61,13 +68,29 @@ class ThinkingSphinx::IndexSet
61
68
  all_indices.select { |index| references.include? index.reference }
62
69
  end
63
70
 
71
+ def instances
72
+ options[:instances] || []
73
+ end
74
+
75
+ def mti_classes
76
+ classes.reject { |klass|
77
+ klass.column_names.include?(klass.inheritance_column)
78
+ }
79
+ end
80
+
64
81
  def references
65
82
  options[:references] || classes_and_ancestors.collect { |klass|
66
- klass.name.underscore.to_sym
83
+ self.class.reference_name(klass)
67
84
  }
68
85
  end
69
86
 
70
87
  def references_specified?
71
88
  options[:references] && options[:references].any?
72
89
  end
90
+
91
+ def sti_classes
92
+ classes.select { |klass|
93
+ klass.column_names.include?(klass.inheritance_column)
94
+ }
95
+ end
73
96
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::IndexingStrategies::AllAtOnce
4
+ def self.call(indices = [], &block)
5
+ indices << '--all' if indices.empty?
6
+
7
+ block.call indices
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::IndexingStrategies::OneAtATime
4
+ def self.call(indices = [], &block)
5
+ if indices.empty?
6
+ configuration = ThinkingSphinx::Configuration.instance
7
+ configuration.preload_indices
8
+
9
+ indices = configuration.indices.select { |index|
10
+ !(index.distributed? || index.type == 'rt')
11
+ }.collect &:name
12
+ end
13
+
14
+ indices.each { |name| block.call [name] }
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Interfaces::Base
4
+ include ThinkingSphinx::WithOutput
5
+
6
+ private
7
+
8
+ def command(command, extra_options = {})
9
+ ThinkingSphinx::Commander.call(
10
+ command, configuration, options.merge(extra_options), stream
11
+ )
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Interfaces::Daemon < ThinkingSphinx::Interfaces::Base
4
+ def start
5
+ if command :running
6
+ raise ThinkingSphinx::SphinxAlreadyRunning, 'searchd is already running'
7
+ end
8
+
9
+ command(options[:nodetach] ? :start_attached : :start_detached)
10
+ end
11
+
12
+ def status
13
+ if command :running
14
+ stream.puts "The Sphinx daemon searchd is currently running."
15
+ else
16
+ stream.puts "The Sphinx daemon searchd is not currently running."
17
+ end
18
+ end
19
+
20
+ def stop
21
+ command :stop
22
+ end
23
+
24
+ private
25
+
26
+ delegate :controller, :to => :configuration
27
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Interfaces::RealTime < ThinkingSphinx::Interfaces::Base
4
+ def initialize(configuration, options, stream = STDOUT)
5
+ super
6
+
7
+ configuration.preload_indices
8
+
9
+ command :prepare
10
+ end
11
+
12
+ def clear
13
+ command :clear_real_time, :indices => indices
14
+ end
15
+
16
+ def index
17
+ return if indices.empty?
18
+ if !command :running
19
+ stream.puts <<-TXT
20
+ The Sphinx daemon is not currently running. Real-time indices can only be
21
+ populated by sending commands to a running daemon.
22
+ TXT
23
+ return
24
+ end
25
+
26
+ command :index_real_time, :indices => indices
27
+ end
28
+
29
+ private
30
+
31
+ def index_names
32
+ @index_names ||= options[:index_names] || []
33
+ end
34
+
35
+ def indices
36
+ @indices ||= begin
37
+ indices = configuration.indices.select { |index| index.type == 'rt' }
38
+
39
+ if index_names.any?
40
+ indices.select! { |index| index_names.include? index.name }
41
+ end
42
+
43
+ indices
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Interfaces::SQL < ThinkingSphinx::Interfaces::Base
4
+ def initialize(configuration, options, stream = STDOUT)
5
+ super
6
+
7
+ configuration.preload_indices
8
+
9
+ command :prepare
10
+ end
11
+
12
+ def clear
13
+ command :clear_sql, :indices => (filtered? ? filtered_indices : indices)
14
+ end
15
+
16
+ def index(reconfigure = true, verbose = nil)
17
+ stream.puts <<-TXT unless verbose.nil?
18
+ The verbose argument to the index method is now deprecated, and can instead be
19
+ managed by the :verbose option passed in when initialising RakeInterface. That
20
+ option is set automatically when invoked by rake, via rake's --silent and/or
21
+ --quiet arguments.
22
+ TXT
23
+ return if indices.empty?
24
+
25
+ command :configure if reconfigure
26
+ command :index_sql,
27
+ :indices => (filtered? ? filtered_indices.collect(&:name) : nil)
28
+ end
29
+
30
+ def merge
31
+ command :merge_and_update
32
+ end
33
+
34
+ private
35
+
36
+ def filtered?
37
+ index_names.any?
38
+ end
39
+
40
+ def filtered_indices
41
+ indices.select { |index| index_names.include? index.name }
42
+ end
43
+
44
+ def index_names
45
+ @index_names ||= options[:index_names] || []
46
+ end
47
+
48
+ def indices
49
+ @indices ||= configuration.indices.select do |index|
50
+ index.type == 'plain' || index.type.blank?
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx::Interfaces
4
+ #
5
+ end
6
+
7
+ require 'thinking_sphinx/interfaces/base'
8
+ require 'thinking_sphinx/interfaces/daemon'
9
+ require 'thinking_sphinx/interfaces/real_time'
10
+ require 'thinking_sphinx/interfaces/sql'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Logger
2
4
  def self.log(notification, message, &block)
3
5
  ActiveSupport::Notifications.instrument(
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Masks::GroupEnumeratorsMask
2
4
  def initialize(search)
3
5
  @search = search
@@ -9,20 +11,20 @@ class ThinkingSphinx::Masks::GroupEnumeratorsMask
9
11
 
10
12
  def each_with_count(&block)
11
13
  @search.raw.each_with_index do |row, index|
12
- yield @search[index], row[ThinkingSphinx::SphinxQL.count[:column]]
14
+ yield @search[index], row["sphinx_internal_count"]
13
15
  end
14
16
  end
15
17
 
16
18
  def each_with_group(&block)
17
19
  @search.raw.each_with_index do |row, index|
18
- yield @search[index], row[ThinkingSphinx::SphinxQL.group_by[:column]]
20
+ yield @search[index], row["sphinx_internal_group"]
19
21
  end
20
22
  end
21
23
 
22
24
  def each_with_group_and_count(&block)
23
25
  @search.raw.each_with_index do |row, index|
24
- yield @search[index], row[ThinkingSphinx::SphinxQL.group_by[:column]],
25
- row[ThinkingSphinx::SphinxQL.count[:column]]
26
+ yield @search[index], row["sphinx_internal_group"],
27
+ row["sphinx_internal_count"]
26
28
  end
27
29
  end
28
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Masks::PaginationMask
2
4
  def initialize(search)
3
5
  @search = search
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Masks::ScopesMask
2
4
  def initialize(search)
3
5
  @search = search
@@ -24,6 +26,12 @@ class ThinkingSphinx::Masks::ScopesMask
24
26
  search query, options.merge(:ids_only => true)
25
27
  end
26
28
 
29
+ def none
30
+ ThinkingSphinx::Search::Merger.new(@search).merge! nil, :none => true
31
+ end
32
+
33
+ alias_method :search_none, :none
34
+
27
35
  private
28
36
 
29
37
  def apply_scope(scope, *args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Masks::WeightEnumeratorMask
2
4
  def initialize(search)
3
5
  @search = search
@@ -9,7 +11,7 @@ class ThinkingSphinx::Masks::WeightEnumeratorMask
9
11
 
10
12
  def each_with_weight(&block)
11
13
  @search.raw.each_with_index do |row, index|
12
- yield @search[index], row[ThinkingSphinx::SphinxQL.weight[:column]]
14
+ yield @search[index], row["weight()"]
13
15
  end
14
16
  end
15
17
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ThinkingSphinx::Masks
2
4
  #
3
5
  end
@@ -1,6 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
2
4
  ThinkingSphinx::Middlewares::Middleware
3
5
 
6
+ NO_MODEL = Struct.new(:primary_key).new(:id).freeze
7
+ NO_INDEX = Struct.new(:primary_key).new(:id).freeze
8
+
4
9
  def call(contexts)
5
10
  contexts.each do |context|
6
11
  Inner.new(context).call
@@ -36,12 +41,25 @@ class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
36
41
  }.compact
37
42
  end
38
43
 
44
+ def index_for(model)
45
+ return NO_INDEX unless context[:indices]
46
+
47
+ context[:indices].detect { |index| index.model == model } || NO_INDEX
48
+ end
49
+
39
50
  def model_names
40
51
  @model_names ||= context[:results].collect { |row|
41
52
  row['sphinx_internal_class']
42
53
  }.uniq
43
54
  end
44
55
 
56
+ def primary_key_for(model)
57
+ model = NO_MODEL unless model.respond_to?(:primary_key)
58
+
59
+ @primary_keys ||= {}
60
+ @primary_keys[model] ||= index_for(model).primary_key
61
+ end
62
+
45
63
  def reset_memos
46
64
  @model_names = nil
47
65
  @results_for_models = nil
@@ -49,27 +67,32 @@ class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
49
67
 
50
68
  def result_for(row)
51
69
  results_for_models[row['sphinx_internal_class']].detect { |record|
52
- record.id == row['sphinx_internal_id']
70
+ record.public_send(
71
+ primary_key_for(record.class)
72
+ ) == row['sphinx_internal_id']
53
73
  }
54
74
  end
55
75
 
56
76
  def results_for_models
57
77
  @results_for_models ||= model_names.inject({}) do |hash, name|
58
78
  model = name.constantize
59
- hash[name] = model_relation_with_sql_options(model.unscoped).where(
60
- model.primary_key => ids_for_model(name)
79
+
80
+ model_sql_options = sql_options[name] || sql_options
81
+
82
+ hash[name] = model_relation_with_sql_options(model.unscoped, model_sql_options).where(
83
+ primary_key_for(model) => ids_for_model(name)
61
84
  )
62
85
 
63
86
  hash
64
87
  end
65
88
  end
66
89
 
67
- def model_relation_with_sql_options(relation)
68
- relation = relation.includes sql_options[:include] if sql_options[:include]
69
- relation = relation.joins sql_options[:joins] if sql_options[:joins]
70
- relation = relation.order sql_options[:order] if sql_options[:order]
71
- relation = relation.select sql_options[:select] if sql_options[:select]
72
- relation = relation.group sql_options[:group] if sql_options[:group]
90
+ def model_relation_with_sql_options(relation, model_sql_options)
91
+ relation = relation.includes model_sql_options[:include] if model_sql_options[:include]
92
+ relation = relation.joins model_sql_options[:joins] if model_sql_options[:joins]
93
+ relation = relation.order model_sql_options[:order] if model_sql_options[:order]
94
+ relation = relation.select model_sql_options[:select] if model_sql_options[:select]
95
+ relation = relation.group model_sql_options[:group] if model_sql_options[:group]
73
96
  relation
74
97
  end
75
98
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/module/delegation'
2
4
 
3
5
  class ThinkingSphinx::Middlewares::Geographer <
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Middlewares::Glazier <
2
4
  ThinkingSphinx::Middlewares::Middleware
3
5
 
@@ -14,6 +16,7 @@ class ThinkingSphinx::Middlewares::Glazier <
14
16
  class Inner
15
17
  def initialize(context)
16
18
  @context = context
19
+ @indices = {}
17
20
  end
18
21
 
19
22
  def call
@@ -29,10 +32,20 @@ class ThinkingSphinx::Middlewares::Glazier <
29
32
 
30
33
  attr_reader :context
31
34
 
35
+ def indices_for(model)
36
+ @indices[model] ||= context[:indices].select do |index|
37
+ index.model == model
38
+ end
39
+ end
40
+
32
41
  def row_for(result)
42
+ ids = indices_for(result.class).collect do |index|
43
+ result.send index.primary_key
44
+ end
45
+
33
46
  context[:raw].detect { |row|
34
47
  row['sphinx_internal_class'] == result.class.name &&
35
- row['sphinx_internal_id'] == result.id
48
+ ids.include?(row['sphinx_internal_id'])
36
49
  }
37
50
  end
38
51
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Middlewares::IdsOnly <
2
4
  ThinkingSphinx::Middlewares::Middleware
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Middlewares::Inquirer <
2
4
  ThinkingSphinx::Middlewares::Middleware
3
5
 
@@ -45,7 +47,7 @@ class ThinkingSphinx::Middlewares::Inquirer <
45
47
 
46
48
  def call(raw_results, meta_results)
47
49
  context[:results] = raw_results.to_a
48
- context[:raw] = raw_results
50
+ context[:raw] = context[:results].dup
49
51
  context[:meta] = meta_results.inject({}) { |hash, row|
50
52
  hash[row['Variable_name']] = row['Value']
51
53
  hash
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Middlewares::Middleware
2
4
  def initialize(app)
3
5
  @app = app
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Middlewares::SphinxQL <
2
4
  ThinkingSphinx::Middlewares::Middleware
3
5
 
4
6
  SELECT_OPTIONS = [:agent_query_timeout, :boolean_simplify, :comment, :cutoff,
5
7
  :field_weights, :global_idf, :idf, :index_weights, :max_matches,
6
8
  :max_query_time, :max_predicted_time, :ranker, :retry_count, :retry_delay,
7
- :reverse_scan, :sort_method]
9
+ :reverse_scan, :sort_method, :rand_seed]
8
10
 
9
11
  def call(contexts)
10
12
  contexts.each do |context|
@@ -80,19 +82,6 @@ class ThinkingSphinx::Middlewares::SphinxQL <
80
82
  end.flatten
81
83
  end
82
84
 
83
- def indices_match_classes?
84
- indices.collect(&:reference).uniq.sort == classes.collect { |klass|
85
- klass.name.underscore.to_sym
86
- }.sort
87
- end
88
-
89
- def inheritance_column_select(klass)
90
- <<-SQL
91
- SELECT DISTINCT #{klass.inheritance_column}
92
- FROM #{klass.table_name}
93
- SQL
94
- end
95
-
96
85
  def exclusive_filters
97
86
  @exclusive_filters ||= (options[:without] || {}).tap do |without|
98
87
  without[:sphinx_internal_id] = options[:without_ids] if options[:without_ids].present?
@@ -142,6 +131,19 @@ SQL
142
131
  end
143
132
  end
144
133
 
134
+ def indices_match_classes?
135
+ indices.collect(&:reference).uniq.sort == classes.collect { |klass|
136
+ configuration.index_set_class.reference_name(klass)
137
+ }.sort
138
+ end
139
+
140
+ def inheritance_column_select(klass)
141
+ <<-SQL
142
+ SELECT DISTINCT #{klass.inheritance_column}
143
+ FROM #{klass.table_name}
144
+ SQL
145
+ end
146
+
145
147
  def order_clause
146
148
  order_by = options[:order]
147
149
  order_by = "#{order_by} ASC" if order_by.is_a? Symbol
@@ -159,8 +161,8 @@ SQL
159
161
 
160
162
  def values
161
163
  options[:select] ||= ['*',
162
- "#{ThinkingSphinx::SphinxQL.group_by[:select]}",
163
- "#{ThinkingSphinx::SphinxQL.count[:select]}"
164
+ "groupby() AS sphinx_internal_group",
165
+ "id AS sphinx_document_id, count(DISTINCT sphinx_document_id) AS sphinx_internal_count"
164
166
  ].join(', ') if group_attribute.present?
165
167
  options[:select]
166
168
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ThinkingSphinx::Middlewares::StaleIdChecker <
2
4
  ThinkingSphinx::Middlewares::Middleware
3
5
 
@@ -33,7 +35,7 @@ class ThinkingSphinx::Middlewares::StaleIdChecker <
33
35
  end
34
36
 
35
37
  def raise_exception
36
- raise ThinkingSphinx::Search::StaleIdsException, stale_ids
38
+ raise ThinkingSphinx::Search::StaleIdsException.new(stale_ids, context)
37
39
  end
38
40
 
39
41
  def stale_ids