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,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::IndexSet
4
+ include Enumerable
5
+
6
+ def self.reference_name(klass)
7
+ @cached_results ||= {}
8
+ @cached_results[klass.name] ||= klass.name.underscore.to_sym
9
+ end
10
+
11
+ delegate :each, :empty?, :to => :indices
12
+
13
+ def initialize(options = {}, configuration = nil)
14
+ @options = options
15
+ @index_names = options[:indices] || []
16
+ @configuration = configuration || ThinkingSphinx::Configuration.instance
17
+ end
18
+
19
+ def ancestors
20
+ classes_and_ancestors - classes
21
+ end
22
+
23
+ def to_a
24
+ indices
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :configuration, :options
30
+
31
+ def all_indices
32
+ configuration.preload_indices
33
+ configuration.indices
34
+ end
35
+
36
+ def classes
37
+ options[:classes] || instances.collect(&:class)
38
+ end
39
+
40
+ def classes_specified?
41
+ instances.any? || classes.any? || references_specified?
42
+ end
43
+
44
+ def classes_and_ancestors
45
+ @classes_and_ancestors ||= mti_classes + sti_classes.collect { |model|
46
+ model.ancestors.take_while { |klass|
47
+ klass != ActiveRecord::Base
48
+ }.select { |klass|
49
+ klass.class == Class
50
+ }
51
+ }.flatten
52
+ end
53
+
54
+ def index_names
55
+ options[:indices] || []
56
+ end
57
+
58
+ def indices
59
+ return all_indices.select { |index|
60
+ index_names.include?(index.name)
61
+ } if index_names.any?
62
+
63
+ everything = classes_specified? ? indices_for_references : all_indices
64
+ everything.reject &:distributed?
65
+ end
66
+
67
+ def indices_for_references
68
+ all_indices.select { |index| references.include? index.reference }
69
+ end
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
+
81
+ def references
82
+ options[:references] || classes_and_ancestors.collect { |klass|
83
+ self.class.reference_name(klass)
84
+ }
85
+ end
86
+
87
+ def references_specified?
88
+ options[:references] && options[:references].any?
89
+ end
90
+
91
+ def sti_classes
92
+ classes.select { |klass|
93
+ klass.column_names.include?(klass.inheritance_column)
94
+ }
95
+ end
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'
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Logger
4
+ def self.log(notification, message, &block)
5
+ ActiveSupport::Notifications.instrument(
6
+ "#{notification}.thinking_sphinx", notification => message, &block
7
+ )
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Masks::GroupEnumeratorsMask
4
+ def initialize(search)
5
+ @search = search
6
+ end
7
+
8
+ def can_handle?(method)
9
+ public_methods(false).include?(method)
10
+ end
11
+
12
+ def each_with_count(&block)
13
+ @search.raw.each_with_index do |row, index|
14
+ yield @search[index], row["sphinx_internal_count"]
15
+ end
16
+ end
17
+
18
+ def each_with_group(&block)
19
+ @search.raw.each_with_index do |row, index|
20
+ yield @search[index], row["sphinx_internal_group"]
21
+ end
22
+ end
23
+
24
+ def each_with_group_and_count(&block)
25
+ @search.raw.each_with_index do |row, index|
26
+ yield @search[index], row["sphinx_internal_group"],
27
+ row["sphinx_internal_count"]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Masks::PaginationMask
4
+ def initialize(search)
5
+ @search = search
6
+ end
7
+
8
+ def can_handle?(method)
9
+ public_methods(false).include?(method)
10
+ end
11
+
12
+ def first_page?
13
+ search.current_page == 1
14
+ end
15
+
16
+ def last_page?
17
+ next_page.nil?
18
+ end
19
+
20
+ def next_page
21
+ search.current_page >= total_pages ? nil : search.current_page + 1
22
+ end
23
+
24
+ def next_page?
25
+ !next_page.nil?
26
+ end
27
+
28
+ def page(number)
29
+ search.options[:page] = number
30
+ search
31
+ end
32
+
33
+ def per(limit)
34
+ search.options[:limit] = limit
35
+ search
36
+ end
37
+
38
+ def previous_page
39
+ search.current_page == 1 ? nil : search.current_page - 1
40
+ end
41
+
42
+ alias_method :prev_page, :previous_page
43
+
44
+ def total_entries
45
+ search.meta['total_found'].to_i
46
+ end
47
+
48
+ alias_method :total_count, :total_entries
49
+ alias_method :count, :total_entries
50
+
51
+ def total_pages
52
+ return 0 if search.meta['total'].nil?
53
+
54
+ @total_pages ||= (search.meta['total'].to_i / search.per_page.to_f).ceil
55
+ end
56
+
57
+ alias_method :page_count, :total_pages
58
+ alias_method :num_pages, :total_pages
59
+
60
+ private
61
+
62
+ attr_reader :search
63
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Masks::ScopesMask
4
+ def initialize(search)
5
+ @search = search
6
+ end
7
+
8
+ def can_handle?(method)
9
+ public_methods(false).include?(method) || can_apply_scope?(method)
10
+ end
11
+
12
+ def facets(query = nil, options = {})
13
+ search = ThinkingSphinx.facets query, options
14
+ ThinkingSphinx::Search::Merger.new(search).merge!(
15
+ @search.query, @search.options
16
+ )
17
+ end
18
+
19
+ def search(query = nil, options = {})
20
+ query, options = nil, query if query.is_a?(Hash)
21
+ ThinkingSphinx::Search::Merger.new(@search).merge! query, options
22
+ end
23
+
24
+ def search_for_ids(query = nil, options = {})
25
+ query, options = nil, query if query.is_a?(Hash)
26
+ search query, options.merge(:ids_only => true)
27
+ end
28
+
29
+ def none
30
+ ThinkingSphinx::Search::Merger.new(@search).merge! nil, :none => true
31
+ end
32
+
33
+ alias_method :search_none, :none
34
+
35
+ private
36
+
37
+ def apply_scope(scope, *args)
38
+ query, options = sphinx_scopes[scope].call(*args)
39
+ search query, options
40
+ end
41
+
42
+ def can_apply_scope?(scope)
43
+ @search.options[:classes].present? &&
44
+ @search.options[:classes].length == 1 &&
45
+ @search.options[:classes].first.respond_to?(:sphinx_scopes) &&
46
+ sphinx_scopes[scope].present?
47
+ end
48
+
49
+ def method_missing(method, *args, &block)
50
+ apply_scope method, *args
51
+ end
52
+
53
+ def sphinx_scopes
54
+ @search.options[:classes].first.sphinx_scopes
55
+ end
56
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Masks::WeightEnumeratorMask
4
+ def initialize(search)
5
+ @search = search
6
+ end
7
+
8
+ def can_handle?(method)
9
+ public_methods(false).include?(method)
10
+ end
11
+
12
+ def each_with_weight(&block)
13
+ @search.raw.each_with_index do |row, index|
14
+ yield @search[index], row["weight()"]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx::Masks
4
+ #
5
+ end
6
+
7
+ require 'thinking_sphinx/masks/group_enumerators_mask'
8
+ require 'thinking_sphinx/masks/pagination_mask'
9
+ require 'thinking_sphinx/masks/scopes_mask'
10
+ require 'thinking_sphinx/masks/weight_enumerator_mask'
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::Middlewares::ActiveRecordTranslator <
4
+ ThinkingSphinx::Middlewares::Middleware
5
+
6
+ NO_MODEL = Struct.new(:primary_key).new(:id).freeze
7
+ NO_INDEX = Struct.new(:primary_key).new(:id).freeze
8
+
9
+ def call(contexts)
10
+ contexts.each do |context|
11
+ Inner.new(context).call
12
+ end
13
+
14
+ app.call contexts
15
+ end
16
+
17
+ private
18
+
19
+ class Inner
20
+ def initialize(context)
21
+ @context = context
22
+ end
23
+
24
+ def call
25
+ results_for_models # load now to avoid segfaults
26
+
27
+ context[:results] = if sql_options[:order]
28
+ results_for_models.values.first
29
+ else
30
+ context[:results].collect { |row| result_for(row) }
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :context
37
+
38
+ def ids_for_model(model_name)
39
+ context[:results].collect { |row|
40
+ row['sphinx_internal_id'] if row['sphinx_internal_class'] == model_name
41
+ }.compact
42
+ end
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
+
50
+ def model_names
51
+ @model_names ||= context[:results].collect { |row|
52
+ row['sphinx_internal_class']
53
+ }.uniq
54
+ end
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
+
63
+ def reset_memos
64
+ @model_names = nil
65
+ @results_for_models = nil
66
+ end
67
+
68
+ def result_for(row)
69
+ results_for_models[row['sphinx_internal_class']].detect { |record|
70
+ record.public_send(
71
+ primary_key_for(record.class)
72
+ ) == row['sphinx_internal_id']
73
+ }
74
+ end
75
+
76
+ def results_for_models
77
+ @results_for_models ||= model_names.inject({}) do |hash, name|
78
+ model = name.constantize
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)
84
+ )
85
+
86
+ hash
87
+ end
88
+ end
89
+
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]
96
+ relation
97
+ end
98
+
99
+ def sql_options
100
+ context.search.options[:sql] || {}
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/module/delegation'
4
+
5
+ class ThinkingSphinx::Middlewares::Geographer <
6
+ ThinkingSphinx::Middlewares::Middleware
7
+
8
+ def call(contexts)
9
+ contexts.each do |context|
10
+ Inner.new(context).call
11
+ end
12
+
13
+ app.call contexts
14
+ end
15
+
16
+ private
17
+
18
+ class Inner
19
+ def initialize(context)
20
+ @context = context
21
+ end
22
+
23
+ def call
24
+ return unless geo
25
+
26
+ context[:sphinxql].prepend_values geodist_clause
27
+ context[:panes] << ThinkingSphinx::Panes::DistancePane
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :context
33
+
34
+ delegate :geo, :latitude, :longitude, :to => :geolocation_attributes
35
+
36
+ def fixed_format(float)
37
+ ThinkingSphinx::FloatFormatter.new(float).fixed
38
+ end
39
+
40
+ def geolocation_attributes
41
+ @geolocation_attributes ||= GeolocationAttributes.new(context)
42
+ end
43
+
44
+ def geodist_clause
45
+ "GEODIST(#{fixed_format geo.first}, #{fixed_format geo.last}, #{latitude}, #{longitude}) AS geodist"
46
+ end
47
+
48
+ class GeolocationAttributes
49
+ attr_accessor :latitude, :longitude
50
+
51
+ def initialize(context)
52
+ self.context = context
53
+ self.latitude = latitude_attr if latitude_attr
54
+ self.longitude = longitude_attr if longitude_attr
55
+ end
56
+
57
+ def geo
58
+ search_context_options[:geo]
59
+ end
60
+
61
+ def latitude
62
+ @latitude ||= names.detect { |name| %w[lat latitude].include?(name) } || 'lat'
63
+ end
64
+
65
+ def longitude
66
+ @longitude ||= names.detect { |name| %w[lng longitude].include?(name) } || 'lng'
67
+ end
68
+
69
+ private
70
+
71
+ attr_accessor :context
72
+
73
+ def latitude_attr
74
+ @latitude_attr ||= search_context_options[:latitude_attr]
75
+ end
76
+
77
+ def longitude_attr
78
+ @longitude_attr ||= search_context_options[:longitude_attr]
79
+ end
80
+
81
+ def indices
82
+ context[:indices]
83
+ end
84
+
85
+ def names
86
+ @names ||= indices.collect(&:unique_attribute_names).flatten.uniq
87
+ end
88
+
89
+ def search_context_options
90
+ @search_context_options ||= context.search.options
91
+ end
92
+ end
93
+ end
94
+ end