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,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::PropertyQuery
4
+ def initialize(property, source, type = nil)
5
+ @property, @source, @type = property, source, type
6
+ end
7
+
8
+ def to_s
9
+ if unsafe_habtm_column?
10
+ raise <<-MESSAGE
11
+ Source queries cannot be used with HABTM joins if they use anything beyond the
12
+ primary key.
13
+ MESSAGE
14
+ end
15
+
16
+ if safe_habtm_column?
17
+ ThinkingSphinx::ActiveRecord::SimpleManyQuery.new(
18
+ property, source, type
19
+ ).to_s
20
+ else
21
+ "#{identifier} from #{source_type}; #{queries.join('; ')}"
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :property, :source, :type
28
+
29
+ delegate :unscoped, :to => :base_association_class, :prefix => true
30
+ delegate :sql, :to => Arel
31
+
32
+ def base_association
33
+ reflections.first
34
+ end
35
+
36
+ def base_association_class
37
+ base_association.klass
38
+ end
39
+
40
+ def column
41
+ @column ||= property.columns.first
42
+ end
43
+
44
+ def extend_reflection(reflection)
45
+ return [reflection] unless reflection.through_reflection
46
+
47
+ [reflection.through_reflection, reflection.source_reflection]
48
+ end
49
+
50
+ def identifier
51
+ [type, property.name].compact.join(' ')
52
+ end
53
+
54
+ def joins
55
+ @joins ||= begin
56
+ remainder = reflections.collect(&:name)[1..-1]
57
+ return nil if remainder.empty?
58
+ return remainder.first if remainder.length == 1
59
+
60
+ remainder[0..-2].reverse.inject(remainder.last) { |value, key|
61
+ {key => value}
62
+ }
63
+ end
64
+ end
65
+
66
+ def macros
67
+ reflections.collect &:macro
68
+ end
69
+
70
+ def offset
71
+ "* #{ThinkingSphinx::Configuration.instance.indices.count} + #{source.offset}"
72
+ end
73
+
74
+ def queries
75
+ queries = []
76
+ if column.string?
77
+ queries << column.__name.strip.gsub(/\n/, "\\\n")
78
+ else
79
+ queries << to_sql
80
+ queries << range_sql if ranged?
81
+ end
82
+ queries
83
+ end
84
+
85
+ def quoted_foreign_key
86
+ quote_with_table(base_association_class.table_name, base_association.foreign_key)
87
+ end
88
+
89
+ def quoted_primary_key
90
+ quote_with_table(reflections.last.klass.table_name, column.__name)
91
+ end
92
+
93
+ def quote_with_table(table, column)
94
+ "#{quote_column(table)}.#{quote_column(column)}"
95
+ end
96
+
97
+ def quote_column(column)
98
+ ActiveRecord::Base.connection.quote_column_name(column)
99
+ end
100
+
101
+ def ranged?
102
+ property.source_type == :ranged_query
103
+ end
104
+
105
+ def range_sql
106
+ base_association_class_unscoped.select(
107
+ "MIN(#{quoted_foreign_key}), MAX(#{quoted_foreign_key})"
108
+ ).to_sql
109
+ end
110
+
111
+ def reflections
112
+ @reflections ||= begin
113
+ base = source.model
114
+
115
+ column.__stack.collect { |key|
116
+ reflection = base.reflect_on_association key
117
+ base = reflection.klass
118
+
119
+ extend_reflection reflection
120
+ }.flatten
121
+ end
122
+ end
123
+
124
+ def safe_habtm_column?
125
+ macros == [:has_and_belongs_to_many] && column.__name == :id
126
+ end
127
+
128
+ def source_type
129
+ property.source_type.to_s.dasherize
130
+ end
131
+
132
+ def to_sql
133
+ raise "Could not determine SQL for MVA" if reflections.empty?
134
+
135
+ relation = base_association_class_unscoped.select("#{quoted_foreign_key} #{offset} AS #{quote_column('id')}, #{quoted_primary_key} AS #{quote_column(property.name)}")
136
+ relation = relation.joins(joins) if joins.present?
137
+ relation = relation.where("#{quoted_foreign_key} BETWEEN $start AND $end") if ranged?
138
+ relation = relation.where("#{quoted_foreign_key} IS NOT NULL")
139
+ relation = relation.order(sql("#{quoted_foreign_key} ASC")) if type.nil?
140
+
141
+ relation.to_sql
142
+ end
143
+
144
+ def unsafe_habtm_column?
145
+ macros.include?(:has_and_belongs_to_many) && (
146
+ macros.length > 1 || column.__name != :id
147
+ )
148
+ end
149
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::PropertySQLPresenter
4
+ attr_reader :property, :adapter, :associations
5
+
6
+ def initialize(property, adapter, associations)
7
+ @property, @adapter, @associations = property, adapter, associations
8
+ end
9
+
10
+ def to_group
11
+ return nil if sourced_by_query? || !group?
12
+
13
+ columns_with_table
14
+ end
15
+
16
+ def to_select
17
+ return nil if sourced_by_query?
18
+
19
+ "#{casted_column_with_table} AS #{adapter.quote property.name}"
20
+ end
21
+
22
+ private
23
+
24
+ delegate :multi?, :to => :property
25
+
26
+ def aggregate?
27
+ column_presenters.any? &:aggregate?
28
+ end
29
+
30
+ def aggregate_separator
31
+ multi? ? ',' : ' '
32
+ end
33
+
34
+ def cast_to_timestamp(clause)
35
+ return adapter.cast_to_timestamp clause if property.columns.any?(&:string?)
36
+
37
+ clause.split(', ').collect { |part|
38
+ adapter.cast_to_timestamp part
39
+ }.join(', ')
40
+ end
41
+
42
+ def casted_column_with_table
43
+ clause = columns_with_table
44
+ clause = cast_to_timestamp clause if property.type == :timestamp
45
+ clause = concatenate clause
46
+ if aggregate?
47
+ clause = adapter.group_concatenate(clause, aggregate_separator)
48
+ end
49
+
50
+ clause
51
+ end
52
+
53
+ def column_presenters
54
+ @column_presenters ||= property.columns.collect { |column|
55
+ ThinkingSphinx::ActiveRecord::ColumnSQLPresenter.new(
56
+ property.model, column, adapter, associations
57
+ )
58
+ }
59
+ end
60
+
61
+ def columns_with_table
62
+ column_presenters.collect(&:with_table).compact.join(', ')
63
+ end
64
+
65
+ def concatenating?
66
+ property.columns.length > 1
67
+ end
68
+
69
+ def concatenate(clause)
70
+ return clause unless concatenating?
71
+
72
+ if property.type.nil?
73
+ adapter.concatenate clause, ' '
74
+ else
75
+ clause = clause.split(', ').collect { |part|
76
+ adapter.cast_to_string part
77
+ }.join(', ')
78
+ adapter.concatenate clause, ','
79
+ end
80
+ end
81
+
82
+ def group?
83
+ !(aggregate? || property.columns.any?(&:string?))
84
+ end
85
+
86
+ def sourced_by_query?
87
+ property.source_type.to_s[/query/]
88
+ end
89
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::SimpleManyQuery <
4
+ ThinkingSphinx::ActiveRecord::PropertyQuery
5
+
6
+ def to_s
7
+ "#{identifier} from #{source_type}; #{queries.join('; ')}"
8
+ end
9
+
10
+ private
11
+
12
+ def reflection
13
+ @reflection ||= source.model.reflect_on_association column.__stack.first
14
+ end
15
+
16
+ def quoted_foreign_key
17
+ quote_with_table reflection.join_table, reflection.foreign_key
18
+ end
19
+
20
+ def quoted_primary_key
21
+ quote_with_table reflection.join_table, reflection.association_foreign_key
22
+ end
23
+
24
+ def range_sql
25
+ "SELECT MIN(#{quoted_foreign_key}), MAX(#{quoted_foreign_key}) FROM #{quote_column reflection.join_table}"
26
+ end
27
+
28
+ def to_sql
29
+ selects = [
30
+ "#{quoted_foreign_key} #{offset} AS #{quote_column('id')}",
31
+ "#{quoted_primary_key} AS #{quote_column(property.name)}"
32
+ ]
33
+ sql = "SELECT #{selects.join(', ')} FROM #{quote_column reflection.join_table}"
34
+ sql += " WHERE (#{quoted_foreign_key} BETWEEN $start AND $end)" if ranged?
35
+ sql
36
+ end
37
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::SourceJoins
4
+ def self.call(model, source)
5
+ new(model, source).call
6
+ end
7
+
8
+ def initialize(model, source)
9
+ @model, @source = model, source
10
+ end
11
+
12
+ def call
13
+ append_specified_associations
14
+ append_property_associations
15
+
16
+ joins
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :model, :source
22
+
23
+ def append_property_associations
24
+ source.properties.collect(&:columns).each do |columns|
25
+ columns.each { |column| append_column_associations column }
26
+ end
27
+ end
28
+
29
+ def append_column_associations(column)
30
+ return if column.__stack.empty? or column_included_in_queries?(column)
31
+
32
+ joins.add_join_to column.__stack if column_exists?(column)
33
+ end
34
+
35
+ def append_specified_associations
36
+ source.associations.reject(&:string?).each do |association|
37
+ joins.add_join_to association.stack
38
+ end
39
+ end
40
+
41
+ def column_exists?(column)
42
+ Joiner::Path.new(model, column.__stack).model
43
+ true
44
+ rescue Joiner::AssociationNotFound
45
+ false
46
+ end
47
+
48
+ def joins
49
+ @joins ||= begin
50
+ joins = Joiner::Joins.new model
51
+ if joins.respond_to?(:join_association_class)
52
+ joins.join_association_class = ThinkingSphinx::ActiveRecord::JoinAssociation
53
+ end
54
+ joins
55
+ end
56
+ end
57
+
58
+ def source_query_properties
59
+ source.properties.select { |field| field.source_type == :query }
60
+ end
61
+
62
+ # Use "first" here instead of a more intuitive flatten because flatten
63
+ # will also ask each column to become an Array and that will start
64
+ # to retrieve data.
65
+ def column_included_in_queries?(column)
66
+ source_query_properties.collect(&:columns).collect(&:first).include?(column)
67
+ end
68
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx
4
+ module ActiveRecord
5
+ class SQLBuilder::ClauseBuilder
6
+ def initialize(first_element)
7
+ @clauses = [first_element]
8
+ end
9
+
10
+ def compose(*additions)
11
+ additions.each &method(:add_clause)
12
+
13
+ self
14
+ end
15
+
16
+ def add_clause(clause)
17
+ @clauses += Array(clause)
18
+ end
19
+
20
+ def separated(by = ', ')
21
+ clauses.flatten.compact.join(by)
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :clauses
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx
4
+ module ActiveRecord
5
+ class SQLBuilder::Query
6
+ def initialize(report)
7
+ self.report = report
8
+ self.scope = []
9
+ end
10
+
11
+ def to_query
12
+ filter_by_query_pre
13
+
14
+ scope.compact
15
+ end
16
+
17
+ protected
18
+
19
+ attr_accessor :report, :scope
20
+
21
+ def filter_by_query_pre
22
+ scope_by_time_zone
23
+ scope_by_delta_processor
24
+ scope_by_session
25
+ scope_by_utf8
26
+ end
27
+
28
+ def scope_by_delta_processor
29
+ return unless delta_processor && !source.delta?
30
+
31
+ self.scope << delta_processor.reset_query
32
+ end
33
+
34
+ def scope_by_session
35
+ return unless max_len = source.options[:group_concat_max_len]
36
+
37
+ self.scope << "SET SESSION group_concat_max_len = #{max_len}"
38
+ end
39
+
40
+ def scope_by_time_zone
41
+ return if config.settings['skip_time_zone']
42
+
43
+ self.scope += time_zone_query_pre
44
+ end
45
+
46
+ def scope_by_utf8
47
+ self.scope += utf8_query_pre if source.options[:utf8?]
48
+ end
49
+
50
+ def source
51
+ report.source
52
+ end
53
+
54
+ def method_missing(*args, &block)
55
+ report.send *args, &block
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thinking_sphinx/active_record/sql_builder/clause_builder'
4
+
5
+ module ThinkingSphinx
6
+ module ActiveRecord
7
+ class SQLBuilder::Statement
8
+ def initialize(report)
9
+ @report = report
10
+ @scope = relation
11
+ end
12
+
13
+ def to_relation
14
+ filter_by_scopes
15
+
16
+ scope
17
+ end
18
+
19
+ def to_query_range_relation
20
+ filter_by_query_range
21
+
22
+ scope
23
+ end
24
+
25
+ def to_query_pre
26
+ filter_by_query_pre
27
+
28
+ scope
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :report, :scope
34
+
35
+ def custom_joins
36
+ @custom_joins ||= source.associations.select(&:string?).collect(&:to_s)
37
+ end
38
+
39
+ def filter_by_query_range
40
+ minimum = convert_nulls "MIN(#{quoted_primary_key})", 1
41
+ maximum = convert_nulls "MAX(#{quoted_primary_key})", 1
42
+
43
+ @scope = scope.select("#{minimum}, #{maximum}").where(
44
+ where_clause(true)
45
+ )
46
+ end
47
+
48
+ def filter_by_scopes
49
+ scope_by_select
50
+ scope_by_where_clause
51
+ scope_by_group_clause
52
+ scope_by_joins
53
+ scope_by_custom_joins
54
+ scope_by_order
55
+ end
56
+
57
+ def attribute_presenters
58
+ @attribute_presenters ||= property_sql_presenters_for source.attributes
59
+ end
60
+
61
+ def field_presenters
62
+ @field_presenters ||= property_sql_presenters_for source.fields
63
+ end
64
+
65
+ def presenters_to_group(presenters)
66
+ presenters.collect(&:to_group)
67
+ end
68
+
69
+ def presenters_to_select(presenters)
70
+ presenters.collect(&:to_select)
71
+ end
72
+
73
+ def property_sql_presenters_for(properties)
74
+ properties.collect { |property| property_sql_presenter_for(property) }
75
+ end
76
+
77
+ def property_sql_presenter_for(property)
78
+ ThinkingSphinx::ActiveRecord::PropertySQLPresenter.new(
79
+ property, source.adapter, associations
80
+ )
81
+ end
82
+
83
+ def scope_by_select
84
+ @scope = scope.select(pre_select + select_clause)
85
+ end
86
+
87
+ def scope_by_where_clause
88
+ @scope = scope.where where_clause
89
+ end
90
+
91
+ def scope_by_group_clause
92
+ @scope = scope.group(group_clause)
93
+ end
94
+
95
+ def scope_by_joins
96
+ @scope = scope.joins(associations.join_values)
97
+ end
98
+
99
+ def scope_by_custom_joins
100
+ @scope = scope.joins(custom_joins) if custom_joins.any?
101
+ end
102
+
103
+ def scope_by_order
104
+ @scope = scope.order('NULL') if source.type == 'mysql'
105
+ end
106
+
107
+ def source
108
+ report.source
109
+ end
110
+
111
+ def method_missing(*args, &block)
112
+ report.send *args, &block
113
+ end
114
+
115
+ def select_clause
116
+ SQLBuilder::ClauseBuilder.new(document_id).compose(
117
+ presenters_to_select(field_presenters),
118
+ presenters_to_select(attribute_presenters)
119
+ ).separated
120
+ end
121
+
122
+ def where_clause(for_range = false)
123
+ builder = SQLBuilder::ClauseBuilder.new(nil)
124
+ builder.add_clause delta_processor.clause(source.delta?) if delta_processor
125
+ builder.add_clause range_condition unless for_range
126
+ builder.separated(' AND ')
127
+ end
128
+
129
+ def group_clause
130
+ builder = SQLBuilder::ClauseBuilder.new(quoted_primary_key)
131
+
132
+ builder.compose(
133
+ presenters_to_group(field_presenters),
134
+ presenters_to_group(attribute_presenters)
135
+ ) unless minimal_group_by?
136
+
137
+ builder.compose(groupings).separated
138
+ end
139
+
140
+ def minimal_group_by?
141
+ source.options[:minimal_group_by?] ||
142
+ config.settings['minimal_group_by?'] ||
143
+ config.settings['minimal_group_by']
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx
4
+ module ActiveRecord
5
+ class SQLBuilder
6
+ attr_reader :source
7
+
8
+ def initialize(source)
9
+ @source = source
10
+ end
11
+
12
+ def sql_query
13
+ statement.to_relation.to_sql.gsub(/\n/, "\\\n")
14
+ end
15
+
16
+ def sql_query_range
17
+ return nil if source.disable_range?
18
+ statement.to_query_range_relation.to_sql
19
+ end
20
+
21
+ def sql_query_pre
22
+ query.to_query
23
+ end
24
+
25
+ private
26
+
27
+ delegate :adapter, :model, :delta_processor, :to => :source
28
+ delegate :convert_nulls, :time_zone_query_pre, :utf8_query_pre,
29
+ :cast_to_bigint, :to => :adapter
30
+
31
+ def query
32
+ Query.new(self)
33
+ end
34
+
35
+ def statement
36
+ Statement.new(self)
37
+ end
38
+
39
+ def config
40
+ ThinkingSphinx::Configuration.instance
41
+ end
42
+
43
+ def relation
44
+ model.unscoped
45
+ end
46
+
47
+ def associations
48
+ @associations ||= ThinkingSphinx::ActiveRecord::SourceJoins.call(
49
+ model, source
50
+ )
51
+ end
52
+
53
+ def quote_column(column)
54
+ model.connection.quote_column_name(column)
55
+ end
56
+
57
+ def quoted_primary_key
58
+ "#{model.quoted_table_name}.#{quote_column(source.primary_key)}"
59
+ end
60
+
61
+ def quoted_inheritance_column
62
+ "#{model.quoted_table_name}.#{quote_column(model.inheritance_column)}"
63
+ end
64
+
65
+ def pre_select
66
+ ('SQL_NO_CACHE ' if source.type == 'mysql').to_s
67
+ end
68
+
69
+ def big_document_ids?
70
+ source.options[:big_document_ids] || config.settings['big_document_ids']
71
+ end
72
+
73
+ def document_id
74
+ quoted_alias = quote_column source.primary_key
75
+ column = quoted_primary_key
76
+ column = cast_to_bigint column if big_document_ids?
77
+ column = "#{column} * #{config.indices.count} + #{source.offset}"
78
+
79
+ "#{column} AS #{quoted_alias}"
80
+ end
81
+
82
+ def range_condition
83
+ condition = []
84
+ condition << "#{quoted_primary_key} BETWEEN $start AND $end" unless source.disable_range?
85
+ condition += source.conditions
86
+ condition
87
+ end
88
+
89
+ def groupings
90
+ groupings = source.groupings
91
+ if model.column_names.include?(model.inheritance_column)
92
+ groupings << quoted_inheritance_column
93
+ end
94
+ groupings
95
+ end
96
+
97
+ def model_name
98
+ klass = model.name
99
+ klass = klass.demodulize unless model.store_full_sti_class
100
+ klass
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ require 'thinking_sphinx/active_record/sql_builder/statement'
107
+ require 'thinking_sphinx/active_record/sql_builder/query'