thinking-sphinx 1.2.13 → 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 (517) hide show
  1. checksums.yaml +7 -0
  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 +18 -0
  6. data/.travis.yml +36 -0
  7. data/Appraisals +71 -0
  8. data/CHANGELOG.markdown +782 -0
  9. data/Gemfile +18 -0
  10. data/LICENCE +1 -1
  11. data/Procfile.support +2 -0
  12. data/README.textile +91 -136
  13. data/Rakefile +26 -0
  14. data/bin/console +15 -0
  15. data/bin/loadsphinx +99 -0
  16. data/bin/testmatrix +48 -0
  17. data/lib/thinking/sphinx.rb +3 -0
  18. data/lib/thinking-sphinx.rb +3 -0
  19. data/lib/thinking_sphinx/active_record/association.rb +19 -0
  20. data/lib/thinking_sphinx/active_record/association_proxy/attribute_finder.rb +44 -0
  21. data/lib/thinking_sphinx/active_record/association_proxy/attribute_matcher.rb +40 -0
  22. data/lib/thinking_sphinx/active_record/association_proxy.rb +34 -0
  23. data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +52 -0
  24. data/lib/thinking_sphinx/active_record/attribute/type.rb +106 -0
  25. data/lib/thinking_sphinx/active_record/attribute/values.rb +20 -0
  26. data/lib/thinking_sphinx/active_record/attribute.rb +22 -0
  27. data/lib/thinking_sphinx/active_record/base.rb +91 -0
  28. data/lib/thinking_sphinx/active_record/callbacks/association_delta_callbacks.rb +21 -0
  29. data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +27 -0
  30. data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +66 -0
  31. data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +78 -0
  32. data/lib/thinking_sphinx/active_record/column.rb +44 -0
  33. data/lib/thinking_sphinx/active_record/column_sql_presenter.rb +54 -0
  34. data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +19 -0
  35. data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +51 -0
  36. data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +47 -0
  37. data/lib/thinking_sphinx/active_record/database_adapters.rb +59 -0
  38. data/lib/thinking_sphinx/active_record/depolymorph/association_reflection.rb +32 -0
  39. data/lib/thinking_sphinx/active_record/depolymorph/base_reflection.rb +32 -0
  40. data/lib/thinking_sphinx/active_record/depolymorph/conditions_reflection.rb +40 -0
  41. data/lib/thinking_sphinx/active_record/depolymorph/overridden_reflection.rb +50 -0
  42. data/lib/thinking_sphinx/active_record/depolymorph/scoped_reflection.rb +26 -0
  43. data/lib/thinking_sphinx/active_record/field.rb +18 -0
  44. data/lib/thinking_sphinx/active_record/filter_reflection.rb +18 -0
  45. data/lib/thinking_sphinx/active_record/index.rb +71 -0
  46. data/lib/thinking_sphinx/active_record/interpreter.rb +77 -0
  47. data/lib/thinking_sphinx/active_record/join_association.rb +17 -0
  48. data/lib/thinking_sphinx/active_record/log_subscriber.rb +37 -0
  49. data/lib/thinking_sphinx/active_record/polymorpher.rb +64 -0
  50. data/lib/thinking_sphinx/active_record/property.rb +30 -0
  51. data/lib/thinking_sphinx/active_record/property_query.rb +149 -0
  52. data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +89 -0
  53. data/lib/thinking_sphinx/active_record/simple_many_query.rb +37 -0
  54. data/lib/thinking_sphinx/active_record/source_joins.rb +68 -0
  55. data/lib/thinking_sphinx/active_record/sql_builder/clause_builder.rb +29 -0
  56. data/lib/thinking_sphinx/active_record/sql_builder/query.rb +59 -0
  57. data/lib/thinking_sphinx/active_record/sql_builder/statement.rb +147 -0
  58. data/lib/thinking_sphinx/active_record/sql_builder.rb +107 -0
  59. data/lib/thinking_sphinx/active_record/sql_source/template.rb +55 -0
  60. data/lib/thinking_sphinx/active_record/sql_source.rb +173 -0
  61. data/lib/thinking_sphinx/active_record.rb +39 -301
  62. data/lib/thinking_sphinx/attribute_types.rb +72 -0
  63. data/lib/thinking_sphinx/batched_search.rb +28 -0
  64. data/lib/thinking_sphinx/callbacks/appender.rb +63 -0
  65. data/lib/thinking_sphinx/callbacks.rb +44 -0
  66. data/lib/thinking_sphinx/capistrano/v2.rb +60 -0
  67. data/lib/thinking_sphinx/capistrano/v3.rb +104 -0
  68. data/lib/thinking_sphinx/capistrano.rb +10 -0
  69. data/lib/thinking_sphinx/commander.rb +27 -0
  70. data/lib/thinking_sphinx/commands/base.rb +53 -0
  71. data/lib/thinking_sphinx/commands/clear_real_time.rb +22 -0
  72. data/lib/thinking_sphinx/commands/clear_sql.rb +18 -0
  73. data/lib/thinking_sphinx/commands/configure.rb +15 -0
  74. data/lib/thinking_sphinx/commands/index_real_time.rb +15 -0
  75. data/lib/thinking_sphinx/commands/index_sql.rb +25 -0
  76. data/lib/thinking_sphinx/commands/merge.rb +27 -0
  77. data/lib/thinking_sphinx/commands/merge_and_update.rb +57 -0
  78. data/lib/thinking_sphinx/commands/prepare.rb +15 -0
  79. data/lib/thinking_sphinx/commands/rotate.rb +13 -0
  80. data/lib/thinking_sphinx/commands/running.rb +15 -0
  81. data/lib/thinking_sphinx/commands/start_attached.rb +22 -0
  82. data/lib/thinking_sphinx/commands/start_detached.rb +21 -0
  83. data/lib/thinking_sphinx/commands/stop.rb +24 -0
  84. data/lib/thinking_sphinx/commands.rb +20 -0
  85. data/lib/thinking_sphinx/configuration/consistent_ids.rb +35 -0
  86. data/lib/thinking_sphinx/configuration/defaults.rb +7 -0
  87. data/lib/thinking_sphinx/configuration/distributed_indices.rb +31 -0
  88. data/lib/thinking_sphinx/configuration/duplicate_names.rb +36 -0
  89. data/lib/thinking_sphinx/configuration/minimum_fields.rb +36 -0
  90. data/lib/thinking_sphinx/configuration.rb +196 -269
  91. data/lib/thinking_sphinx/connection/client.rb +74 -0
  92. data/lib/thinking_sphinx/connection/jruby.rb +58 -0
  93. data/lib/thinking_sphinx/connection/mri.rb +26 -0
  94. data/lib/thinking_sphinx/connection.rb +73 -0
  95. data/lib/thinking_sphinx/core/field.rb +11 -0
  96. data/lib/thinking_sphinx/core/index.rb +110 -0
  97. data/lib/thinking_sphinx/core/interpreter.rb +25 -0
  98. data/lib/thinking_sphinx/core/property.rb +15 -0
  99. data/lib/thinking_sphinx/core/settings.rb +11 -0
  100. data/lib/thinking_sphinx/core.rb +11 -0
  101. data/lib/thinking_sphinx/deletion.rb +70 -0
  102. data/lib/thinking_sphinx/deltas/default_delta.rb +57 -66
  103. data/lib/thinking_sphinx/deltas/delete_job.rb +27 -0
  104. data/lib/thinking_sphinx/deltas/index_job.rb +28 -0
  105. data/lib/thinking_sphinx/deltas.rb +52 -27
  106. data/lib/thinking_sphinx/distributed/index.rb +46 -0
  107. data/lib/thinking_sphinx/distributed.rb +7 -0
  108. data/lib/thinking_sphinx/errors.rb +96 -0
  109. data/lib/thinking_sphinx/excerpter.rb +36 -19
  110. data/lib/thinking_sphinx/facet.rb +29 -122
  111. data/lib/thinking_sphinx/facet_search.rb +132 -125
  112. data/lib/thinking_sphinx/float_formatter.rb +35 -0
  113. data/lib/thinking_sphinx/frameworks/plain.rb +10 -0
  114. data/lib/thinking_sphinx/frameworks/rails.rb +11 -0
  115. data/lib/thinking_sphinx/frameworks.rb +11 -0
  116. data/lib/thinking_sphinx/guard/file.rb +28 -0
  117. data/lib/thinking_sphinx/guard/files.rb +40 -0
  118. data/lib/thinking_sphinx/guard/none.rb +7 -0
  119. data/lib/thinking_sphinx/guard.rb +9 -0
  120. data/lib/thinking_sphinx/hooks/guard_presence.rb +34 -0
  121. data/lib/thinking_sphinx/index.rb +50 -92
  122. data/lib/thinking_sphinx/index_set.rb +96 -0
  123. data/lib/thinking_sphinx/indexing_strategies/all_at_once.rb +9 -0
  124. data/lib/thinking_sphinx/indexing_strategies/one_at_a_time.rb +16 -0
  125. data/lib/thinking_sphinx/interfaces/base.rb +13 -0
  126. data/lib/thinking_sphinx/interfaces/daemon.rb +27 -0
  127. data/lib/thinking_sphinx/interfaces/real_time.rb +46 -0
  128. data/lib/thinking_sphinx/interfaces/sql.rb +53 -0
  129. data/lib/thinking_sphinx/interfaces.rb +10 -0
  130. data/lib/thinking_sphinx/logger.rb +9 -0
  131. data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +30 -0
  132. data/lib/thinking_sphinx/masks/pagination_mask.rb +63 -0
  133. data/lib/thinking_sphinx/masks/scopes_mask.rb +56 -0
  134. data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +17 -0
  135. data/lib/thinking_sphinx/masks.rb +10 -0
  136. data/lib/thinking_sphinx/middlewares/active_record_translator.rb +103 -0
  137. data/lib/thinking_sphinx/middlewares/geographer.rb +94 -0
  138. data/lib/thinking_sphinx/middlewares/glazier.rb +52 -0
  139. data/lib/thinking_sphinx/middlewares/ids_only.rb +15 -0
  140. data/lib/thinking_sphinx/middlewares/inquirer.rb +64 -0
  141. data/lib/thinking_sphinx/middlewares/middleware.rb +11 -0
  142. data/lib/thinking_sphinx/middlewares/sphinxql.rb +256 -0
  143. data/lib/thinking_sphinx/middlewares/stale_id_checker.rb +47 -0
  144. data/lib/thinking_sphinx/middlewares/stale_id_filter.rb +48 -0
  145. data/lib/thinking_sphinx/middlewares/valid_options.rb +25 -0
  146. data/lib/thinking_sphinx/middlewares.rb +35 -0
  147. data/lib/thinking_sphinx/panes/attributes_pane.rb +11 -0
  148. data/lib/thinking_sphinx/panes/distance_pane.rb +15 -0
  149. data/lib/thinking_sphinx/panes/excerpts_pane.rb +43 -0
  150. data/lib/thinking_sphinx/panes/weight_pane.rb +11 -0
  151. data/lib/thinking_sphinx/panes.rb +10 -0
  152. data/lib/thinking_sphinx/processor.rb +71 -0
  153. data/lib/thinking_sphinx/query.rb +11 -0
  154. data/lib/thinking_sphinx/railtie.rb +38 -0
  155. data/lib/thinking_sphinx/rake_interface.rb +34 -0
  156. data/lib/thinking_sphinx/real_time/attribute.rb +27 -0
  157. data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +60 -0
  158. data/lib/thinking_sphinx/real_time/field.rb +9 -0
  159. data/lib/thinking_sphinx/real_time/index/template.rb +52 -0
  160. data/lib/thinking_sphinx/real_time/index.rb +102 -0
  161. data/lib/thinking_sphinx/real_time/interpreter.rb +54 -0
  162. data/lib/thinking_sphinx/real_time/populator.rb +46 -0
  163. data/lib/thinking_sphinx/real_time/processor.rb +36 -0
  164. data/lib/thinking_sphinx/real_time/property.rb +21 -0
  165. data/lib/thinking_sphinx/real_time/transcribe_instance.rb +38 -0
  166. data/lib/thinking_sphinx/real_time/transcriber.rb +89 -0
  167. data/lib/thinking_sphinx/real_time/translator.rb +39 -0
  168. data/lib/thinking_sphinx/real_time.rb +40 -0
  169. data/lib/thinking_sphinx/scopes.rb +34 -0
  170. data/lib/thinking_sphinx/search/batch_inquirer.rb +23 -0
  171. data/lib/thinking_sphinx/search/context.rb +31 -0
  172. data/lib/thinking_sphinx/search/glaze.rb +39 -0
  173. data/lib/thinking_sphinx/search/merger.rb +34 -0
  174. data/lib/thinking_sphinx/search/query.rb +33 -0
  175. data/lib/thinking_sphinx/search/stale_ids_exception.rb +15 -0
  176. data/lib/thinking_sphinx/search.rb +166 -704
  177. data/lib/thinking_sphinx/settings.rb +128 -0
  178. data/lib/thinking_sphinx/sinatra.rb +7 -0
  179. data/lib/thinking_sphinx/subscribers/populator_subscriber.rb +48 -0
  180. data/lib/thinking_sphinx/tasks.rb +70 -150
  181. data/lib/thinking_sphinx/test.rb +56 -0
  182. data/lib/thinking_sphinx/utf8.rb +18 -0
  183. data/lib/thinking_sphinx/wildcard.rb +42 -0
  184. data/lib/thinking_sphinx/with_output.rb +13 -0
  185. data/lib/thinking_sphinx.rb +83 -185
  186. data/spec/acceptance/association_scoping_spec.rb +65 -0
  187. data/spec/acceptance/attribute_access_spec.rb +58 -0
  188. data/spec/acceptance/attribute_updates_spec.rb +18 -0
  189. data/spec/acceptance/batch_searching_spec.rb +23 -0
  190. data/spec/acceptance/big_integers_spec.rb +61 -0
  191. data/spec/acceptance/excerpts_spec.rb +50 -0
  192. data/spec/acceptance/facets_spec.rb +141 -0
  193. data/spec/acceptance/geosearching_spec.rb +70 -0
  194. data/spec/acceptance/grouping_by_attributes_spec.rb +79 -0
  195. data/spec/acceptance/index_options_spec.rb +154 -0
  196. data/spec/acceptance/indexing_spec.rb +38 -0
  197. data/spec/acceptance/merging_spec.rb +90 -0
  198. data/spec/acceptance/paginating_search_results_spec.rb +42 -0
  199. data/spec/acceptance/real_time_updates_spec.rb +115 -0
  200. data/spec/acceptance/remove_deleted_records_spec.rb +99 -0
  201. data/spec/acceptance/search_counts_spec.rb +20 -0
  202. data/spec/acceptance/search_for_just_ids_spec.rb +21 -0
  203. data/spec/acceptance/searching_across_models_spec.rb +47 -0
  204. data/spec/acceptance/searching_across_schemas_spec.rb +40 -0
  205. data/spec/acceptance/searching_on_fields_spec.rb +59 -0
  206. data/spec/acceptance/searching_with_filters_spec.rb +159 -0
  207. data/spec/acceptance/searching_with_sti_spec.rb +76 -0
  208. data/spec/acceptance/searching_within_a_model_spec.rb +117 -0
  209. data/spec/acceptance/sorting_search_results_spec.rb +50 -0
  210. data/spec/acceptance/spec_helper.rb +6 -0
  211. data/spec/acceptance/specifying_sql_spec.rb +516 -0
  212. data/spec/acceptance/sphinx_scopes_spec.rb +87 -0
  213. data/spec/acceptance/sql_deltas_spec.rb +78 -0
  214. data/spec/acceptance/support/database_cleaner.rb +13 -0
  215. data/spec/acceptance/support/sphinx_controller.rb +62 -0
  216. data/spec/acceptance/support/sphinx_helpers.rb +45 -0
  217. data/spec/acceptance/suspended_deltas_spec.rb +56 -0
  218. data/spec/fixtures/database.yml +4 -0
  219. data/spec/internal/app/indices/admin_person_index.rb +9 -0
  220. data/spec/internal/app/indices/album_index.rb +9 -0
  221. data/spec/internal/app/indices/animal_index.rb +5 -0
  222. data/spec/internal/app/indices/article_index.rb +31 -0
  223. data/spec/internal/app/indices/bird_index.rb +6 -0
  224. data/spec/internal/app/indices/book_index.rb +11 -0
  225. data/spec/internal/app/indices/car_index.rb +7 -0
  226. data/spec/internal/app/indices/city_index.rb +9 -0
  227. data/spec/internal/app/indices/colour_index.rb +7 -0
  228. data/spec/internal/app/indices/product_index.rb +27 -0
  229. data/spec/internal/app/indices/tee_index.rb +6 -0
  230. data/spec/internal/app/indices/user_index.rb +9 -0
  231. data/spec/internal/app/models/admin/person.rb +9 -0
  232. data/spec/internal/app/models/album.rb +25 -0
  233. data/spec/internal/app/models/animal.rb +5 -0
  234. data/spec/internal/app/models/article.rb +9 -0
  235. data/spec/internal/app/models/bird.rb +5 -0
  236. data/spec/internal/app/models/book.rb +18 -0
  237. data/spec/internal/app/models/car.rb +7 -0
  238. data/spec/internal/app/models/categorisation.rb +15 -0
  239. data/spec/internal/app/models/category.rb +6 -0
  240. data/spec/internal/app/models/city.rb +7 -0
  241. data/spec/internal/app/models/colour.rb +7 -0
  242. data/spec/internal/app/models/event.rb +5 -0
  243. data/spec/internal/app/models/flightless_bird.rb +4 -0
  244. data/spec/internal/app/models/genre.rb +5 -0
  245. data/spec/internal/app/models/hardcover.rb +5 -0
  246. data/spec/internal/app/models/mammal.rb +4 -0
  247. data/spec/internal/app/models/manufacturer.rb +5 -0
  248. data/spec/internal/app/models/product.rb +8 -0
  249. data/spec/internal/app/models/tag.rb +6 -0
  250. data/{features/support → spec/internal/app}/models/tagging.rb +3 -1
  251. data/spec/internal/app/models/tee.rb +10 -0
  252. data/spec/internal/app/models/tweet.rb +5 -0
  253. data/spec/internal/app/models/user.rb +10 -0
  254. data/spec/internal/config/database.yml +17 -0
  255. data/spec/internal/db/schema.rb +115 -0
  256. data/spec/internal/tmp/.gitkeep +0 -0
  257. data/spec/spec_helper.rb +29 -0
  258. data/spec/support/json_column.rb +35 -0
  259. data/spec/support/multi_schema.rb +50 -0
  260. data/spec/support/mysql.rb +25 -0
  261. data/spec/support/sphinx_yaml_helpers.rb +16 -0
  262. data/spec/thinking_sphinx/active_record/association_spec.rb +14 -0
  263. data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +165 -0
  264. data/spec/thinking_sphinx/active_record/base_spec.rb +131 -0
  265. data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +128 -0
  266. data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +176 -0
  267. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +91 -0
  268. data/spec/thinking_sphinx/active_record/column_spec.rb +72 -0
  269. data/spec/thinking_sphinx/active_record/column_sql_presenter_spec.rb +39 -0
  270. data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +33 -0
  271. data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +70 -0
  272. data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +66 -0
  273. data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +128 -0
  274. data/spec/thinking_sphinx/active_record/field_spec.rb +51 -0
  275. data/spec/thinking_sphinx/active_record/filter_reflection_spec.rb +207 -0
  276. data/spec/thinking_sphinx/active_record/index_spec.rb +220 -0
  277. data/spec/thinking_sphinx/active_record/interpreter_spec.rb +329 -0
  278. data/spec/thinking_sphinx/active_record/polymorpher_spec.rb +87 -0
  279. data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +264 -0
  280. data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +662 -0
  281. data/spec/thinking_sphinx/active_record/sql_source_spec.rb +507 -0
  282. data/spec/thinking_sphinx/attribute_types_spec.rb +52 -0
  283. data/spec/thinking_sphinx/commands/clear_real_time_spec.rb +46 -0
  284. data/spec/thinking_sphinx/commands/clear_sql_spec.rb +52 -0
  285. data/spec/thinking_sphinx/commands/configure_spec.rb +31 -0
  286. data/spec/thinking_sphinx/commands/index_real_time_spec.rb +33 -0
  287. data/spec/thinking_sphinx/commands/index_sql_spec.rb +86 -0
  288. data/spec/thinking_sphinx/commands/merge_and_update_spec.rb +106 -0
  289. data/spec/thinking_sphinx/commands/merge_spec.rb +48 -0
  290. data/spec/thinking_sphinx/commands/prepare_spec.rb +31 -0
  291. data/spec/thinking_sphinx/commands/running_spec.rb +30 -0
  292. data/spec/thinking_sphinx/commands/start_detached_spec.rb +67 -0
  293. data/spec/thinking_sphinx/commands/stop_spec.rb +63 -0
  294. data/spec/thinking_sphinx/configuration/minimum_fields_spec.rb +60 -0
  295. data/spec/thinking_sphinx/configuration_spec.rb +582 -0
  296. data/spec/thinking_sphinx/connection/mri_spec.rb +49 -0
  297. data/spec/thinking_sphinx/connection_spec.rb +87 -0
  298. data/spec/thinking_sphinx/deletion_spec.rb +57 -0
  299. data/spec/thinking_sphinx/deltas/default_delta_spec.rb +123 -0
  300. data/spec/thinking_sphinx/deltas_spec.rb +77 -0
  301. data/spec/thinking_sphinx/errors_spec.rb +103 -0
  302. data/spec/thinking_sphinx/excerpter_spec.rb +53 -0
  303. data/spec/thinking_sphinx/facet_search_spec.rb +133 -0
  304. data/spec/thinking_sphinx/hooks/guard_presence_spec.rb +30 -0
  305. data/spec/thinking_sphinx/index_set_spec.rb +132 -0
  306. data/spec/thinking_sphinx/index_spec.rb +140 -0
  307. data/spec/thinking_sphinx/interfaces/daemon_spec.rb +60 -0
  308. data/spec/thinking_sphinx/interfaces/real_time_spec.rb +109 -0
  309. data/spec/thinking_sphinx/interfaces/sql_spec.rb +122 -0
  310. data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +123 -0
  311. data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +139 -0
  312. data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +180 -0
  313. data/spec/thinking_sphinx/middlewares/geographer_spec.rb +102 -0
  314. data/spec/thinking_sphinx/middlewares/glazier_spec.rb +65 -0
  315. data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +72 -0
  316. data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +401 -0
  317. data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +50 -0
  318. data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +113 -0
  319. data/spec/thinking_sphinx/middlewares/valid_options_spec.rb +51 -0
  320. data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +23 -0
  321. data/spec/thinking_sphinx/panes/distance_pane_spec.rb +43 -0
  322. data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +53 -0
  323. data/spec/thinking_sphinx/panes/weight_pane_spec.rb +22 -0
  324. data/spec/thinking_sphinx/rake_interface_spec.rb +39 -0
  325. data/spec/thinking_sphinx/real_time/attribute_spec.rb +64 -0
  326. data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +238 -0
  327. data/spec/thinking_sphinx/real_time/field_spec.rb +69 -0
  328. data/spec/thinking_sphinx/real_time/index_spec.rb +230 -0
  329. data/spec/thinking_sphinx/real_time/interpreter_spec.rb +203 -0
  330. data/spec/thinking_sphinx/real_time/transcribe_instance_spec.rb +35 -0
  331. data/spec/thinking_sphinx/real_time/transcriber_spec.rb +109 -0
  332. data/spec/thinking_sphinx/real_time/translator_spec.rb +17 -0
  333. data/spec/thinking_sphinx/scopes_spec.rb +51 -0
  334. data/spec/thinking_sphinx/search/glaze_spec.rb +79 -0
  335. data/spec/thinking_sphinx/search/query_spec.rb +87 -0
  336. data/spec/thinking_sphinx/search_spec.rb +214 -0
  337. data/spec/thinking_sphinx/wildcard_spec.rb +53 -0
  338. data/spec/thinking_sphinx_spec.rb +44 -0
  339. data/thinking-sphinx.gemspec +42 -0
  340. metadata +656 -243
  341. data/VERSION.yml +0 -5
  342. data/features/alternate_primary_key.feature +0 -27
  343. data/features/attribute_transformation.feature +0 -22
  344. data/features/attribute_updates.feature +0 -33
  345. data/features/datetime_deltas.feature +0 -66
  346. data/features/delayed_delta_indexing.feature +0 -37
  347. data/features/deleting_instances.feature +0 -64
  348. data/features/direct_attributes.feature +0 -11
  349. data/features/excerpts.feature +0 -13
  350. data/features/extensible_delta_indexing.feature +0 -9
  351. data/features/facets.feature +0 -76
  352. data/features/facets_across_model.feature +0 -29
  353. data/features/handling_edits.feature +0 -92
  354. data/features/retry_stale_indexes.feature +0 -24
  355. data/features/searching_across_models.feature +0 -20
  356. data/features/searching_by_model.feature +0 -175
  357. data/features/searching_with_find_arguments.feature +0 -56
  358. data/features/sphinx_detection.feature +0 -25
  359. data/features/sphinx_scopes.feature +0 -35
  360. data/features/step_definitions/alpha_steps.rb +0 -3
  361. data/features/step_definitions/beta_steps.rb +0 -7
  362. data/features/step_definitions/common_steps.rb +0 -178
  363. data/features/step_definitions/datetime_delta_steps.rb +0 -15
  364. data/features/step_definitions/delayed_delta_indexing_steps.rb +0 -7
  365. data/features/step_definitions/extensible_delta_indexing_steps.rb +0 -7
  366. data/features/step_definitions/facet_steps.rb +0 -92
  367. data/features/step_definitions/find_arguments_steps.rb +0 -36
  368. data/features/step_definitions/gamma_steps.rb +0 -15
  369. data/features/step_definitions/scope_steps.rb +0 -11
  370. data/features/step_definitions/search_steps.rb +0 -89
  371. data/features/step_definitions/sphinx_steps.rb +0 -31
  372. data/features/sti_searching.feature +0 -14
  373. data/features/support/database.example.yml +0 -3
  374. data/features/support/database.yml +0 -5
  375. data/features/support/db/active_record.rb +0 -40
  376. data/features/support/db/database.yml +0 -5
  377. data/features/support/db/fixtures/alphas.rb +0 -10
  378. data/features/support/db/fixtures/authors.rb +0 -1
  379. data/features/support/db/fixtures/betas.rb +0 -10
  380. data/features/support/db/fixtures/boxes.rb +0 -9
  381. data/features/support/db/fixtures/categories.rb +0 -1
  382. data/features/support/db/fixtures/cats.rb +0 -3
  383. data/features/support/db/fixtures/comments.rb +0 -24
  384. data/features/support/db/fixtures/delayed_betas.rb +0 -10
  385. data/features/support/db/fixtures/developers.rb +0 -29
  386. data/features/support/db/fixtures/dogs.rb +0 -3
  387. data/features/support/db/fixtures/extensible_betas.rb +0 -10
  388. data/features/support/db/fixtures/gammas.rb +0 -10
  389. data/features/support/db/fixtures/people.rb +0 -1001
  390. data/features/support/db/fixtures/posts.rb +0 -6
  391. data/features/support/db/fixtures/robots.rb +0 -14
  392. data/features/support/db/fixtures/tags.rb +0 -27
  393. data/features/support/db/fixtures/thetas.rb +0 -10
  394. data/features/support/db/migrations/create_alphas.rb +0 -7
  395. data/features/support/db/migrations/create_animals.rb +0 -5
  396. data/features/support/db/migrations/create_authors.rb +0 -3
  397. data/features/support/db/migrations/create_authors_posts.rb +0 -6
  398. data/features/support/db/migrations/create_betas.rb +0 -5
  399. data/features/support/db/migrations/create_boxes.rb +0 -5
  400. data/features/support/db/migrations/create_categories.rb +0 -3
  401. data/features/support/db/migrations/create_comments.rb +0 -10
  402. data/features/support/db/migrations/create_delayed_betas.rb +0 -17
  403. data/features/support/db/migrations/create_developers.rb +0 -9
  404. data/features/support/db/migrations/create_extensible_betas.rb +0 -5
  405. data/features/support/db/migrations/create_gammas.rb +0 -3
  406. data/features/support/db/migrations/create_people.rb +0 -13
  407. data/features/support/db/migrations/create_posts.rb +0 -5
  408. data/features/support/db/migrations/create_robots.rb +0 -4
  409. data/features/support/db/migrations/create_taggings.rb +0 -5
  410. data/features/support/db/migrations/create_tags.rb +0 -4
  411. data/features/support/db/migrations/create_thetas.rb +0 -5
  412. data/features/support/db/mysql.rb +0 -3
  413. data/features/support/db/postgresql.rb +0 -3
  414. data/features/support/env.rb +0 -18
  415. data/features/support/lib/generic_delta_handler.rb +0 -8
  416. data/features/support/models/alpha.rb +0 -10
  417. data/features/support/models/animal.rb +0 -5
  418. data/features/support/models/author.rb +0 -3
  419. data/features/support/models/beta.rb +0 -8
  420. data/features/support/models/box.rb +0 -8
  421. data/features/support/models/cat.rb +0 -3
  422. data/features/support/models/category.rb +0 -4
  423. data/features/support/models/comment.rb +0 -10
  424. data/features/support/models/delayed_beta.rb +0 -7
  425. data/features/support/models/developer.rb +0 -16
  426. data/features/support/models/dog.rb +0 -3
  427. data/features/support/models/extensible_beta.rb +0 -9
  428. data/features/support/models/gamma.rb +0 -5
  429. data/features/support/models/person.rb +0 -23
  430. data/features/support/models/post.rb +0 -20
  431. data/features/support/models/robot.rb +0 -12
  432. data/features/support/models/tag.rb +0 -3
  433. data/features/support/models/theta.rb +0 -7
  434. data/features/support/post_database.rb +0 -43
  435. data/lib/cucumber/thinking_sphinx/internal_world.rb +0 -125
  436. data/lib/cucumber/thinking_sphinx/sql_logger.rb +0 -20
  437. data/lib/thinking_sphinx/active_record/attribute_updates.rb +0 -48
  438. data/lib/thinking_sphinx/active_record/delta.rb +0 -87
  439. data/lib/thinking_sphinx/active_record/has_many_association.rb +0 -28
  440. data/lib/thinking_sphinx/active_record/scopes.rb +0 -39
  441. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +0 -42
  442. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -54
  443. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +0 -143
  444. data/lib/thinking_sphinx/association.rb +0 -164
  445. data/lib/thinking_sphinx/attribute.rb +0 -341
  446. data/lib/thinking_sphinx/class_facet.rb +0 -15
  447. data/lib/thinking_sphinx/core/array.rb +0 -7
  448. data/lib/thinking_sphinx/core/string.rb +0 -15
  449. data/lib/thinking_sphinx/deltas/datetime_delta.rb +0 -50
  450. data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +0 -24
  451. data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +0 -27
  452. data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +0 -26
  453. data/lib/thinking_sphinx/deltas/delayed_delta.rb +0 -30
  454. data/lib/thinking_sphinx/deploy/capistrano.rb +0 -100
  455. data/lib/thinking_sphinx/field.rb +0 -82
  456. data/lib/thinking_sphinx/index/builder.rb +0 -286
  457. data/lib/thinking_sphinx/index/faux_column.rb +0 -110
  458. data/lib/thinking_sphinx/property.rb +0 -162
  459. data/lib/thinking_sphinx/rails_additions.rb +0 -150
  460. data/lib/thinking_sphinx/search_methods.rb +0 -421
  461. data/lib/thinking_sphinx/source/internal_properties.rb +0 -46
  462. data/lib/thinking_sphinx/source/sql.rb +0 -128
  463. data/lib/thinking_sphinx/source.rb +0 -150
  464. data/rails/init.rb +0 -14
  465. data/spec/lib/thinking_sphinx/active_record/delta_spec.rb +0 -130
  466. data/spec/lib/thinking_sphinx/active_record/has_many_association_spec.rb +0 -49
  467. data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +0 -96
  468. data/spec/lib/thinking_sphinx/active_record_spec.rb +0 -353
  469. data/spec/lib/thinking_sphinx/association_spec.rb +0 -239
  470. data/spec/lib/thinking_sphinx/attribute_spec.rb +0 -507
  471. data/spec/lib/thinking_sphinx/configuration_spec.rb +0 -268
  472. data/spec/lib/thinking_sphinx/core/array_spec.rb +0 -9
  473. data/spec/lib/thinking_sphinx/core/string_spec.rb +0 -9
  474. data/spec/lib/thinking_sphinx/deltas/job_spec.rb +0 -32
  475. data/spec/lib/thinking_sphinx/excerpter_spec.rb +0 -57
  476. data/spec/lib/thinking_sphinx/facet_search_spec.rb +0 -176
  477. data/spec/lib/thinking_sphinx/facet_spec.rb +0 -333
  478. data/spec/lib/thinking_sphinx/field_spec.rb +0 -154
  479. data/spec/lib/thinking_sphinx/index/builder_spec.rb +0 -455
  480. data/spec/lib/thinking_sphinx/index/faux_column_spec.rb +0 -30
  481. data/spec/lib/thinking_sphinx/index_spec.rb +0 -45
  482. data/spec/lib/thinking_sphinx/rails_additions_spec.rb +0 -203
  483. data/spec/lib/thinking_sphinx/search_methods_spec.rb +0 -152
  484. data/spec/lib/thinking_sphinx/search_spec.rb +0 -1101
  485. data/spec/lib/thinking_sphinx/source_spec.rb +0 -227
  486. data/spec/lib/thinking_sphinx_spec.rb +0 -162
  487. data/tasks/distribution.rb +0 -53
  488. data/tasks/rails.rake +0 -1
  489. data/tasks/testing.rb +0 -72
  490. data/vendor/after_commit/LICENSE +0 -20
  491. data/vendor/after_commit/README +0 -16
  492. data/vendor/after_commit/Rakefile +0 -22
  493. data/vendor/after_commit/init.rb +0 -8
  494. data/vendor/after_commit/lib/after_commit/active_record.rb +0 -114
  495. data/vendor/after_commit/lib/after_commit/connection_adapters.rb +0 -103
  496. data/vendor/after_commit/lib/after_commit.rb +0 -45
  497. data/vendor/after_commit/test/after_commit_test.rb +0 -53
  498. data/vendor/delayed_job/lib/delayed/job.rb +0 -251
  499. data/vendor/delayed_job/lib/delayed/message_sending.rb +0 -7
  500. data/vendor/delayed_job/lib/delayed/performable_method.rb +0 -55
  501. data/vendor/delayed_job/lib/delayed/worker.rb +0 -54
  502. data/vendor/riddle/lib/riddle/client/filter.rb +0 -53
  503. data/vendor/riddle/lib/riddle/client/message.rb +0 -66
  504. data/vendor/riddle/lib/riddle/client/response.rb +0 -84
  505. data/vendor/riddle/lib/riddle/client.rb +0 -635
  506. data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +0 -48
  507. data/vendor/riddle/lib/riddle/configuration/index.rb +0 -142
  508. data/vendor/riddle/lib/riddle/configuration/indexer.rb +0 -19
  509. data/vendor/riddle/lib/riddle/configuration/remote_index.rb +0 -17
  510. data/vendor/riddle/lib/riddle/configuration/searchd.rb +0 -25
  511. data/vendor/riddle/lib/riddle/configuration/section.rb +0 -43
  512. data/vendor/riddle/lib/riddle/configuration/source.rb +0 -23
  513. data/vendor/riddle/lib/riddle/configuration/sql_source.rb +0 -34
  514. data/vendor/riddle/lib/riddle/configuration/xml_source.rb +0 -28
  515. data/vendor/riddle/lib/riddle/configuration.rb +0 -33
  516. data/vendor/riddle/lib/riddle/controller.rb +0 -53
  517. data/vendor/riddle/lib/riddle.rb +0 -30
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::Glazier <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ def call(contexts)
7
+ contexts.each do |context|
8
+ Inner.new(context).call
9
+ end
10
+
11
+ app.call contexts
12
+ end
13
+
14
+ private
15
+
16
+ class Inner
17
+ def initialize(context)
18
+ @context = context
19
+ @indices = {}
20
+ end
21
+
22
+ def call
23
+ return if context[:panes].empty?
24
+
25
+ context[:results] = context[:results].collect { |result|
26
+ ThinkingSphinx::Search::Glaze.new context, result, row_for(result),
27
+ context[:panes]
28
+ }
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :context
34
+
35
+ def indices_for(model)
36
+ @indices[model] ||= context[:indices].select do |index|
37
+ index.model == model
38
+ end
39
+ end
40
+
41
+ def row_for(result)
42
+ ids = indices_for(result.class).collect do |index|
43
+ result.send index.primary_key
44
+ end
45
+
46
+ context[:raw].detect { |row|
47
+ row['sphinx_internal_class'] == result.class.name &&
48
+ ids.include?(row['sphinx_internal_id'])
49
+ }
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::IdsOnly <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ def call(contexts)
7
+ contexts.each do |context|
8
+ context[:results] = context[:results].collect { |row|
9
+ row['sphinx_internal_id']
10
+ }
11
+ end
12
+
13
+ app.call contexts
14
+ end
15
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::Inquirer <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ def call(contexts)
7
+ @contexts = contexts
8
+ @batch = nil
9
+
10
+ ThinkingSphinx::Logger.log :query, combined_queries do
11
+ batch.results
12
+ end
13
+
14
+ index = 0
15
+ contexts.each do |context|
16
+ Inner.new(context).call batch.results[index], batch.results[index + 1]
17
+
18
+ index += 2
19
+ end
20
+
21
+ app.call contexts
22
+ end
23
+
24
+ private
25
+
26
+ def batch
27
+ @batch ||= begin
28
+ batch = ThinkingSphinx::Search::BatchInquirer.new
29
+
30
+ @contexts.each do |context|
31
+ batch.append_query context[:sphinxql].to_sql
32
+ batch.append_query Riddle::Query.meta
33
+ end
34
+
35
+ batch
36
+ end
37
+ end
38
+
39
+ def combined_queries
40
+ @contexts.collect { |context| context[:sphinxql].to_sql }.join('; ')
41
+ end
42
+
43
+ class Inner
44
+ def initialize(context)
45
+ @context = context
46
+ end
47
+
48
+ def call(raw_results, meta_results)
49
+ context[:results] = raw_results.to_a
50
+ context[:raw] = context[:results].dup
51
+ context[:meta] = meta_results.inject({}) { |hash, row|
52
+ hash[row['Variable_name']] = row['Value']
53
+ hash
54
+ }
55
+
56
+ total = context[:meta]['total_found']
57
+ ThinkingSphinx::Logger.log :message, "Found #{total} result#{'s' unless total == 1}"
58
+ end
59
+
60
+ private
61
+
62
+ attr_reader :context
63
+ end
64
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::Middleware
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ private
9
+
10
+ attr_reader :app, :context
11
+ end
@@ -0,0 +1,256 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::SphinxQL <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ SELECT_OPTIONS = [:agent_query_timeout, :boolean_simplify, :comment, :cutoff,
7
+ :field_weights, :global_idf, :idf, :index_weights, :max_matches,
8
+ :max_query_time, :max_predicted_time, :ranker, :retry_count, :retry_delay,
9
+ :reverse_scan, :sort_method, :rand_seed]
10
+
11
+ def call(contexts)
12
+ contexts.each do |context|
13
+ Inner.new(context).call
14
+ end
15
+
16
+ app.call contexts
17
+ end
18
+
19
+ private
20
+
21
+ class Inner
22
+ def initialize(context)
23
+ @context = context
24
+ end
25
+
26
+ def call
27
+ context[:indices] = indices
28
+ context[:sphinxql] = statement
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :context
34
+
35
+ delegate :search, :configuration, :to => :context
36
+ delegate :options, :to => :search
37
+ delegate :settings, :to => :configuration
38
+
39
+ def classes
40
+ options[:classes] || []
41
+ end
42
+
43
+ def classes_and_descendants
44
+ classes + descendants
45
+ end
46
+
47
+ def classes_and_descendants_names
48
+ classes_and_descendants.collect do |klass|
49
+ name = klass.name
50
+ name = %Q{"#{name}"} if name[/:/]
51
+ name
52
+ end
53
+ end
54
+
55
+ def classes_with_inheritance_column
56
+ classes.select { |klass|
57
+ klass.column_names.include?(klass.inheritance_column)
58
+ }
59
+ end
60
+
61
+ def class_condition
62
+ "(#{classes_and_descendants_names.join('|')})"
63
+ end
64
+
65
+ def class_condition_required?
66
+ classes.any? && !indices_match_classes?
67
+ end
68
+
69
+ def constantize_inheritance_column(klass)
70
+ values = klass.connection.select_values inheritance_column_select(klass)
71
+ values.reject(&:blank?).each(&:constantize)
72
+ end
73
+
74
+ def descendants
75
+ @descendants ||= options[:skip_sti] ? [] : descendants_from_tables
76
+ end
77
+
78
+ def descendants_from_tables
79
+ classes_with_inheritance_column.collect do |klass|
80
+ constantize_inheritance_column(klass)
81
+ klass.descendants
82
+ end.flatten
83
+ end
84
+
85
+ def exclusive_filters
86
+ @exclusive_filters ||= (options[:without] || {}).tap do |without|
87
+ without[:sphinx_internal_id] = options[:without_ids] if options[:without_ids].present?
88
+ end
89
+ end
90
+
91
+ def extended_query
92
+ conditions = options[:conditions] || {}
93
+ if class_condition_required?
94
+ conditions[:sphinx_internal_class_name] = class_condition
95
+ end
96
+
97
+ @extended_query ||= ThinkingSphinx::Search::Query.new(
98
+ context.search.query, conditions, options[:star]
99
+ ).to_s
100
+ end
101
+
102
+ def group_attribute
103
+ options[:group_by].to_s if options[:group_by]
104
+ end
105
+
106
+ def group_order_clause
107
+ group_by = options[:order_group_by]
108
+ group_by = "#{group_by} ASC" if group_by.is_a? Symbol
109
+ group_by
110
+ end
111
+
112
+ def inclusive_filters
113
+ (options[:with] || {}).merge({:sphinx_deleted => false})
114
+ end
115
+
116
+ def index_names
117
+ indices.collect(&:name)
118
+ end
119
+
120
+ def index_options
121
+ indices.first.options
122
+ end
123
+
124
+ def indices
125
+ @indices ||= begin
126
+ set = configuration.index_set_class.new(
127
+ options.slice(:classes, :indices)
128
+ )
129
+ raise ThinkingSphinx::NoIndicesError if set.empty?
130
+ set
131
+ end
132
+ end
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
+
147
+ def order_clause
148
+ order_by = options[:order]
149
+ order_by = "#{order_by} ASC" if order_by.is_a? Symbol
150
+ order_by
151
+ end
152
+
153
+ def select_options
154
+ @select_options ||= SELECT_OPTIONS.inject({}) do |hash, key|
155
+ hash[key] = settings[key.to_s] if settings.key? key.to_s
156
+ hash[key] = index_options[key] if index_options.key? key
157
+ hash[key] = options[key] if options.key? key
158
+ hash
159
+ end
160
+ end
161
+
162
+ def values
163
+ options[:select] ||= ['*',
164
+ "groupby() AS sphinx_internal_group",
165
+ "id AS sphinx_document_id, count(DISTINCT sphinx_document_id) AS sphinx_internal_count"
166
+ ].join(', ') if group_attribute.present?
167
+ options[:select]
168
+ end
169
+
170
+ def statement
171
+ Statement.new(self).to_riddle_query_select
172
+ end
173
+
174
+ class Statement
175
+ def initialize(report)
176
+ self.report = report
177
+ self.query = Riddle::Query::Select.new
178
+ end
179
+
180
+ def to_riddle_query_select
181
+ filter_by_scopes
182
+
183
+ query
184
+ end
185
+
186
+ protected
187
+ attr_accessor :report, :query
188
+ def filter_by_scopes
189
+ scope_by_from
190
+ scope_by_values
191
+ scope_by_extended_query
192
+ scope_by_inclusive_filters
193
+ scope_by_with_all
194
+ scope_by_exclusive_filters
195
+ scope_by_without_all
196
+
197
+ scope_by_order
198
+ scope_by_group
199
+ scope_by_pagination
200
+ scope_by_options
201
+ end
202
+
203
+ def scope_by_from
204
+ query.from *(index_names.collect { |index| "`#{index}`" })
205
+ end
206
+
207
+ def scope_by_values
208
+ query.values(values.present? ? values : '*')
209
+ end
210
+
211
+ def scope_by_extended_query
212
+ query.matching extended_query if extended_query.present?
213
+ end
214
+
215
+ def scope_by_inclusive_filters
216
+ query.where inclusive_filters if inclusive_filters.any?
217
+ end
218
+
219
+ def scope_by_with_all
220
+ query.where_all options[:with_all] if options[:with_all]
221
+ end
222
+
223
+ def scope_by_exclusive_filters
224
+ query.where_not exclusive_filters if exclusive_filters.any?
225
+ end
226
+
227
+ def scope_by_without_all
228
+ query.where_not_all options[:without_all] if options[:without_all]
229
+ end
230
+
231
+ def scope_by_order
232
+ query.order_by order_clause if order_clause.present?
233
+ end
234
+
235
+ def scope_by_group
236
+ query.group_by group_attribute if group_attribute.present?
237
+ query.group_best options[:group_best] if options[:group_best]
238
+ query.order_within_group_by group_order_clause if group_order_clause.present?
239
+ query.having options[:having] if options[:having]
240
+ end
241
+
242
+ def scope_by_pagination
243
+ query.offset context.search.offset
244
+ query.limit context.search.per_page
245
+ end
246
+
247
+ def scope_by_options
248
+ query.with_options select_options if select_options.keys.any?
249
+ end
250
+
251
+ def method_missing(*args, &block)
252
+ report.send *args, &block
253
+ end
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::StaleIdChecker <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ def call(contexts)
7
+ contexts.each do |context|
8
+ Inner.new(context).call
9
+ end
10
+
11
+ app.call contexts
12
+ end
13
+
14
+ private
15
+
16
+ class Inner
17
+ def initialize(context)
18
+ @context = context
19
+ end
20
+
21
+ def call
22
+ raise_exception if context[:results].any?(&:nil?)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :context
28
+
29
+ def actual_ids
30
+ context[:results].compact.collect(&:id)
31
+ end
32
+
33
+ def expected_ids
34
+ context[:raw].collect { |row| row['sphinx_internal_id'].to_i }
35
+ end
36
+
37
+ def raise_exception
38
+ raise ThinkingSphinx::Search::StaleIdsException.new(stale_ids, context)
39
+ end
40
+
41
+ def stale_ids
42
+ # Currently only works with single-model queries. Has at no point done
43
+ # otherwise, but such an improvement would be nice.
44
+ expected_ids - actual_ids
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::StaleIdFilter <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ def call(contexts)
7
+ @context = contexts.first
8
+ @stale_ids = []
9
+ @retries = stale_retries
10
+
11
+ begin
12
+ app.call contexts
13
+ rescue ThinkingSphinx::Search::StaleIdsException => error
14
+ raise error if @retries <= 0
15
+
16
+ append_stale_ids error.ids, error.context
17
+ ThinkingSphinx::Logger.log :message, log_message
18
+
19
+ @retries -= 1 and retry
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def append_stale_ids(ids, context)
26
+ @stale_ids |= ids
27
+
28
+ context.search.options[:without_ids] ||= []
29
+ context.search.options[:without_ids] |= ids
30
+ end
31
+
32
+ def log_message
33
+ 'Stale Ids (%s %s left): %s' % [
34
+ @retries, (@retries == 1 ? 'try' : 'tries'), @stale_ids.join(', ')
35
+ ]
36
+ end
37
+
38
+ def stale_retries
39
+ case context.search.options[:retry_stale]
40
+ when nil, TrueClass
41
+ 2
42
+ when FalseClass
43
+ 0
44
+ else
45
+ context.search.options[:retry_stale].to_i
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::ValidOptions <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ def call(contexts)
7
+ contexts.each { |context| check_options context.search.options }
8
+
9
+ app.call contexts
10
+ end
11
+
12
+ private
13
+
14
+ def check_options(options)
15
+ unknown = invalid_keys options.keys
16
+ return if unknown.empty?
17
+
18
+ ThinkingSphinx::Logger.log :caution,
19
+ "Unexpected search options: #{unknown.inspect}"
20
+ end
21
+
22
+ def invalid_keys(keys)
23
+ keys - ThinkingSphinx::Search.valid_options
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx::Middlewares; end
4
+
5
+ %w[
6
+ middleware active_record_translator geographer glazier ids_only inquirer
7
+ sphinxql stale_id_checker stale_id_filter valid_options
8
+ ].each do |middleware|
9
+ require "thinking_sphinx/middlewares/#{middleware}"
10
+ end
11
+
12
+ module ThinkingSphinx::Middlewares
13
+ def self.use(builder, middlewares)
14
+ middlewares.each { |m| builder.use m }
15
+ end
16
+
17
+ BASE_MIDDLEWARES = [ValidOptions, SphinxQL, Geographer, Inquirer]
18
+
19
+ DEFAULT = ::Middleware::Builder.new do
20
+ use StaleIdFilter
21
+ ThinkingSphinx::Middlewares.use self, BASE_MIDDLEWARES
22
+ use ActiveRecordTranslator
23
+ use StaleIdChecker
24
+ use Glazier
25
+ end
26
+
27
+ RAW_ONLY = ::Middleware::Builder.new do
28
+ ThinkingSphinx::Middlewares.use self, BASE_MIDDLEWARES
29
+ end
30
+
31
+ IDS_ONLY = ::Middleware::Builder.new do
32
+ ThinkingSphinx::Middlewares.use self, BASE_MIDDLEWARES
33
+ use IdsOnly
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Panes::AttributesPane
4
+ def initialize(context, object, raw)
5
+ @raw = raw
6
+ end
7
+
8
+ def sphinx_attributes
9
+ @raw
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Panes::DistancePane
4
+ def initialize(context, object, raw)
5
+ @raw = raw
6
+ end
7
+
8
+ def distance
9
+ @raw['geodist'].to_f
10
+ end
11
+
12
+ def geodist
13
+ @raw['geodist'].to_f
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Panes::ExcerptsPane
4
+ def initialize(context, object, raw)
5
+ @context, @object = context, object
6
+ end
7
+
8
+ def excerpts
9
+ @excerpt_glazing ||= Excerpts.new @object, excerpter
10
+ end
11
+
12
+ private
13
+
14
+ def excerpter
15
+ @excerpter ||= ThinkingSphinx::Excerpter.new(
16
+ @context[:indices].first.name,
17
+ excerpt_words,
18
+ @context.search.options[:excerpts] || {}
19
+ )
20
+ end
21
+
22
+ def excerpt_words
23
+ @excerpt_words ||= begin
24
+ conditions = @context.search.options[:conditions] || {}
25
+ ThinkingSphinx::Search::Query.new(
26
+ ([@context.search.query] + conditions.values).compact.join(' '),
27
+ {}, @context.search.options[:star]
28
+ ).to_s
29
+ end
30
+ end
31
+
32
+ class Excerpts
33
+ def initialize(object, excerpter)
34
+ @object, @excerpter = object, excerpter
35
+ end
36
+
37
+ private
38
+
39
+ def method_missing(method, *args, &block)
40
+ @excerpter.excerpt! @object.send(method, *args, &block).to_s
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Panes::WeightPane
4
+ def initialize(context, object, raw)
5
+ @raw = raw
6
+ end
7
+
8
+ def weight
9
+ @raw["weight()"]
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx::Panes
4
+ #
5
+ end
6
+
7
+ require 'thinking_sphinx/panes/attributes_pane'
8
+ require 'thinking_sphinx/panes/distance_pane'
9
+ require 'thinking_sphinx/panes/excerpts_pane'
10
+ require 'thinking_sphinx/panes/weight_pane'