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,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Attribute::Type
4
+ UPDATEABLE_TYPES = [:integer, :timestamp, :boolean, :float]
5
+
6
+ def initialize(attribute, model)
7
+ @attribute, @model = attribute, model
8
+ end
9
+
10
+ def multi?
11
+ @multi ||= attribute.options[:multi] || multi_from_associations
12
+ end
13
+
14
+ def timestamp?
15
+ type == :timestamp
16
+ end
17
+
18
+ def type
19
+ @type ||= attribute.options[:type] || type_from_database
20
+ end
21
+
22
+ def type=(value)
23
+ @type = attribute.options[:type] = value
24
+ end
25
+
26
+ def updateable?
27
+ UPDATEABLE_TYPES.include?(type) && single_column_reference?
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :attribute, :model
33
+
34
+ def associations
35
+ @associations ||= begin
36
+ klass = model
37
+ attribute.columns.first.__stack.collect { |name|
38
+ association = klass.reflect_on_association(name)
39
+ klass = association.klass
40
+ association
41
+ }
42
+ end
43
+ end
44
+
45
+ def big_integer?
46
+ type_symbol == :integer && database_column.sql_type[/bigint/i]
47
+ end
48
+
49
+ def column_name
50
+ attribute.columns.first.__name.to_s
51
+ end
52
+
53
+ def database_column
54
+ @database_column ||= klass.columns.detect { |db_column|
55
+ db_column.name == column_name
56
+ }
57
+ end
58
+
59
+ def klass
60
+ @klass ||= associations.any? ? associations.last.klass : model
61
+ end
62
+
63
+ def multi_from_associations
64
+ associations.any? { |association|
65
+ [:has_many, :has_and_belongs_to_many].include?(association.macro)
66
+ }
67
+ end
68
+
69
+ def single_column_reference?
70
+ attribute.columns.length == 1 &&
71
+ attribute.columns.first.__stack.length == 0 &&
72
+ !attribute.columns.first.string?
73
+ end
74
+
75
+ def type_from_database
76
+ raise ThinkingSphinx::MissingColumnError,
77
+ "Cannot determine the database type of column #{column_name}, as it does not exist" if database_column.nil?
78
+
79
+ return :bigint if big_integer?
80
+
81
+ case type_symbol
82
+ when :datetime, :date
83
+ :timestamp
84
+ when :text
85
+ :string
86
+ when :decimal
87
+ :float
88
+ when :integer, :boolean, :timestamp, :float, :string, :bigint, :json
89
+ type_symbol
90
+ else
91
+ raise ThinkingSphinx::UnknownAttributeType,
92
+ <<-ERROR
93
+ Unable to determine an equivalent Sphinx attribute type from #{database_column.type.class.name} for attribute #{attribute.name}. You may want to manually set the type.
94
+
95
+ e.g.
96
+ has my_column, :type => :integer
97
+ ERROR
98
+ end
99
+ end
100
+
101
+ def type_symbol
102
+ return database_column.type if database_column.type.is_a?(Symbol)
103
+
104
+ database_column.type.class.name.demodulize.downcase.to_sym
105
+ end
106
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Attribute::Values
4
+ def initialize(attribute)
5
+ @attribute = attribute
6
+ end
7
+
8
+ def value_for(instance)
9
+ object = column.__stack.inject(instance) { |object, name|
10
+ object.nil? ? nil : object.send(name)
11
+ }
12
+ object.nil? ? nil : object.send(column.__name)
13
+ end
14
+
15
+ private
16
+
17
+ def column
18
+ @attribute.columns.first
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Attribute <
4
+ ThinkingSphinx::ActiveRecord::Property
5
+
6
+ delegate :type, :type=, :multi?, :updateable?, :to => :typist
7
+ delegate :value_for, :to => :values
8
+
9
+ private
10
+
11
+ def typist
12
+ @typist ||= ThinkingSphinx::ActiveRecord::Attribute::Type.new self, @model
13
+ end
14
+
15
+ def values
16
+ @values ||= ThinkingSphinx::ActiveRecord::Attribute::Values.new self
17
+ end
18
+ end
19
+
20
+ require 'thinking_sphinx/active_record/attribute/sphinx_presenter'
21
+ require 'thinking_sphinx/active_record/attribute/type'
22
+ require 'thinking_sphinx/active_record/attribute/values'
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx::ActiveRecord::Base
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ # Avoid method collisions for public Thinking Sphinx methods added to all
8
+ # ActiveRecord models. The `sphinx_`-prefixed versions will always exist,
9
+ # and the non-prefixed versions will be added if a method of that name
10
+ # doesn't already exist.
11
+ #
12
+ # If a method is overwritten later by something else, that's also fine - the
13
+ # prefixed versions will still be there.
14
+ class_module = ThinkingSphinx::ActiveRecord::Base::ClassMethods
15
+ class_module.public_instance_methods.each do |method_name|
16
+ short_method = method_name.to_s.delete_prefix("sphinx_").to_sym
17
+ next if methods.include?(short_method)
18
+
19
+ define_singleton_method(short_method, method(method_name))
20
+ end
21
+
22
+ if ActiveRecord::VERSION::STRING.to_i >= 5
23
+ [
24
+ ::ActiveRecord::Reflection::HasManyReflection,
25
+ ::ActiveRecord::Reflection::HasAndBelongsToManyReflection
26
+ ].each do |reflection_class|
27
+ reflection_class.include DefaultReflectionAssociations
28
+ end
29
+ else
30
+ ::ActiveRecord::Associations::CollectionProxy.include(
31
+ ThinkingSphinx::ActiveRecord::AssociationProxy
32
+ )
33
+ end
34
+ end
35
+
36
+ module DefaultReflectionAssociations
37
+ def extensions
38
+ super + [ThinkingSphinx::ActiveRecord::AssociationProxy]
39
+ end
40
+ end
41
+
42
+ module ClassMethods
43
+ def sphinx_facets(query = nil, options = {})
44
+ merge_search ThinkingSphinx.facets, query, options
45
+ end
46
+
47
+ def sphinx_search(query = nil, options = {})
48
+ merge_search ThinkingSphinx.search, query, options
49
+ end
50
+
51
+ def sphinx_search_count(query = nil, options = {})
52
+ search_for_ids(query, options).total_entries
53
+ end
54
+
55
+ def sphinx_search_for_ids(query = nil, options = {})
56
+ ThinkingSphinx::Search::Merger.new(
57
+ search(query, options)
58
+ ).merge! nil, :ids_only => true
59
+ end
60
+
61
+ def sphinx_search_none
62
+ merge_search ThinkingSphinx.search, nil, none: true
63
+ end
64
+
65
+ private
66
+
67
+ def default_sphinx_scope?
68
+ respond_to?(:default_sphinx_scope) && default_sphinx_scope
69
+ end
70
+
71
+ def default_sphinx_scope_response
72
+ [sphinx_scopes[default_sphinx_scope].call].flatten
73
+ end
74
+
75
+ def merge_search(search, query, options)
76
+ merger = ThinkingSphinx::Search::Merger.new search
77
+
78
+ merger.merge! *default_sphinx_scope_response if default_sphinx_scope?
79
+ merger.merge! query, options
80
+
81
+ if current_scope && !merger.search.options[:ignore_scopes]
82
+ raise ThinkingSphinx::MixedScopesError,
83
+ 'You cannot search with Sphinx through ActiveRecord scopes'
84
+ end
85
+
86
+ result = merger.merge! nil, :classes => [self]
87
+ result.populate if result.options[:populate]
88
+ result
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Callbacks::AssociationDeltaCallbacks
4
+ def initialize(path)
5
+ @path = path
6
+ end
7
+
8
+ def after_commit(instance)
9
+ Array(objects_for(instance)).each do |object|
10
+ object.update :delta => true unless object.frozen?
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :path
17
+
18
+ def objects_for(instance)
19
+ path.inject(instance) { |object, method| object.send method }
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks <
4
+ ThinkingSphinx::Callbacks
5
+
6
+ callbacks :after_commit, :after_destroy, :after_rollback
7
+
8
+ def after_commit
9
+ delete_from_sphinx
10
+ end
11
+
12
+ def after_destroy
13
+ delete_from_sphinx
14
+ end
15
+
16
+ def after_rollback
17
+ delete_from_sphinx
18
+ end
19
+
20
+ private
21
+
22
+ def delete_from_sphinx
23
+ return if ThinkingSphinx::Callbacks.suspended?
24
+
25
+ ThinkingSphinx::Processor.new(instance: instance).delete
26
+ end
27
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks <
4
+ ThinkingSphinx::Callbacks
5
+
6
+ callbacks :after_commit, :before_save
7
+
8
+ def after_commit
9
+ return unless !suspended? && delta_indices? && toggled?
10
+
11
+ delta_indices.each do |index|
12
+ index.delta_processor.index index
13
+ end
14
+
15
+ core_indices.each do |index|
16
+ index.delta_processor.delete index, instance
17
+ end
18
+ end
19
+
20
+ def before_save
21
+ return unless !ThinkingSphinx::Callbacks.suspended? && delta_indices? &&
22
+ new_or_changed?
23
+
24
+ processors.each { |processor| processor.toggle instance }
25
+ end
26
+
27
+ private
28
+
29
+ def config
30
+ ThinkingSphinx::Configuration.instance
31
+ end
32
+
33
+ def core_indices
34
+ @core_indices ||= indices.select(&:delta_processor).reject(&:delta?)
35
+ end
36
+
37
+ def delta_indices
38
+ @delta_indices ||= indices.select &:delta?
39
+ end
40
+
41
+ def delta_indices?
42
+ delta_indices.any?
43
+ end
44
+
45
+ def indices
46
+ @indices ||= config.index_set_class.new(
47
+ :instances => [instance], :classes => [instance.class]
48
+ ).select { |index| index.type == "plain" }
49
+ end
50
+
51
+ def new_or_changed?
52
+ instance.new_record? || instance.changed?
53
+ end
54
+
55
+ def processors
56
+ delta_indices.collect &:delta_processor
57
+ end
58
+
59
+ def suspended?
60
+ ThinkingSphinx::Callbacks.suspended? || ThinkingSphinx::Deltas.suspended?
61
+ end
62
+
63
+ def toggled?
64
+ processors.any? { |processor| processor.toggled?(instance) }
65
+ end
66
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks <
4
+ ThinkingSphinx::Callbacks
5
+
6
+ if ActiveRecord::Base.instance_methods.grep(/saved_changes/).any?
7
+ CHANGED_ATTRIBUTES = lambda { |instance| instance.saved_changes.keys }
8
+ else
9
+ CHANGED_ATTRIBUTES = lambda { |instance| instance.changed }
10
+ end
11
+
12
+ callbacks :after_update
13
+
14
+ def after_update
15
+ return unless !ThinkingSphinx::Callbacks.suspended? && updates_enabled?
16
+
17
+ indices.each do |index|
18
+ update index unless index.distributed?
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def attributes_hash_for(index)
25
+ updateable_attributes_for(index).inject({}) do |hash, attribute|
26
+ if changed_attributes.include?(attribute.columns.first.__name.to_s)
27
+ hash[attribute.name] = attribute.value_for(instance)
28
+ end
29
+
30
+ hash
31
+ end
32
+ end
33
+
34
+ def changed_attributes
35
+ @changed_attributes ||= CHANGED_ATTRIBUTES.call instance
36
+ end
37
+
38
+ def configuration
39
+ ThinkingSphinx::Configuration.instance
40
+ end
41
+
42
+ def indices
43
+ @indices ||= begin
44
+ all = configuration.indices_for_references(reference)
45
+ all.reject { |index| index.type == 'rt' }
46
+ end
47
+ end
48
+
49
+ def reference
50
+ configuration.index_set_class.reference_name(instance.class)
51
+ end
52
+
53
+ def update(index)
54
+ attributes = attributes_hash_for(index)
55
+ return if attributes.empty?
56
+
57
+ sphinxql = Riddle::Query.update(
58
+ index.name,
59
+ index.document_id_for_key(instance.public_send(index.primary_key)),
60
+ attributes
61
+ )
62
+ ThinkingSphinx::Connection.take do |connection|
63
+ connection.execute(sphinxql)
64
+ end
65
+ rescue ThinkingSphinx::ConnectionError => error
66
+ # This isn't vital, so don't raise the error.
67
+ end
68
+
69
+ def updateable_attributes_for(index)
70
+ index.sources.collect(&:attributes).flatten.select { |attribute|
71
+ attribute.updateable?
72
+ }
73
+ end
74
+
75
+ def updates_enabled?
76
+ configuration.settings['attribute_updates']
77
+ end
78
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::Column
4
+ def initialize(*stack)
5
+ @stack = stack
6
+ @name = stack.pop
7
+ end
8
+
9
+ def __name
10
+ @name
11
+ end
12
+
13
+ def __path
14
+ @stack + [@name]
15
+ end
16
+
17
+ def __replace(stack, replacements)
18
+ return [self] if string? || __stack[0..stack.length-1] != stack
19
+
20
+ replacements.collect { |replacement|
21
+ self.class.new *(replacement + __stack[stack.length..-1]), __name
22
+ }
23
+ end
24
+
25
+ def __stack
26
+ @stack
27
+ end
28
+
29
+ def string?
30
+ __name.is_a?(String)
31
+ end
32
+
33
+ def to_ary
34
+ [self]
35
+ end
36
+
37
+ private
38
+
39
+ def method_missing(method, *args, &block)
40
+ @stack << @name
41
+ @name = method
42
+ self
43
+ end
44
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::ColumnSQLPresenter
4
+ def initialize(model, column, adapter, associations)
5
+ @model, @column, @adapter, @associations = model, column, adapter, associations
6
+ end
7
+
8
+ def aggregate?
9
+ path.aggregate?
10
+ rescue Joiner::AssociationNotFound
11
+ false
12
+ end
13
+
14
+ def with_table
15
+ return __name if string?
16
+ return nil unless exists?
17
+
18
+ quoted_table = escape_table? ? escape_table(table) : table
19
+
20
+ "#{quoted_table}.#{adapter.quote __name}"
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :model, :column, :adapter, :associations
26
+
27
+ delegate :__stack, :__name, :string?, :to => :column
28
+
29
+ def escape_table(table_name)
30
+ table_name.split('.').map { |t| adapter.quote(t) }.join('.')
31
+ end
32
+
33
+ def escape_table?
34
+ table[/[`"]/].nil?
35
+ end
36
+
37
+ def exists?
38
+ path.model.column_names.include?(column.__name.to_s)
39
+ rescue Joiner::AssociationNotFound
40
+ false
41
+ end
42
+
43
+ def path
44
+ Joiner::Path.new model, column.__stack
45
+ end
46
+
47
+ def table
48
+ associations.alias_for __stack
49
+ end
50
+
51
+ def version
52
+ ActiveRecord::VERSION
53
+ end
54
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::DatabaseAdapters::AbstractAdapter
4
+ def initialize(model)
5
+ @model = model
6
+ end
7
+
8
+ def quote(column)
9
+ @model.connection.quote_column_name(column)
10
+ end
11
+
12
+ def quoted_table_name
13
+ @model.quoted_table_name
14
+ end
15
+
16
+ def utf8_query_pre
17
+ []
18
+ end
19
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter <
4
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::AbstractAdapter
5
+
6
+ def boolean_value(value)
7
+ value ? 1 : 0
8
+ end
9
+
10
+ def cast_to_bigint(clause)
11
+ "CAST(#{clause} AS UNSIGNED INTEGER)"
12
+ end
13
+
14
+ def cast_to_string(clause)
15
+ "CAST(#{clause} AS char)"
16
+ end
17
+
18
+ def cast_to_timestamp(clause)
19
+ "UNIX_TIMESTAMP(#{clause})"
20
+ end
21
+
22
+ def concatenate(clause, separator = ' ')
23
+ "CONCAT_WS('#{separator}', #{clause})"
24
+ end
25
+
26
+ def convert_nulls(clause, default = '')
27
+ "IFNULL(#{clause}, #{default})"
28
+ end
29
+
30
+ def convert_blank(clause, default = '')
31
+ "COALESCE(NULLIF(#{clause}, ''), #{default})"
32
+ end
33
+
34
+ def group_concatenate(clause, separator = ' ')
35
+ "GROUP_CONCAT(DISTINCT #{clause} SEPARATOR '#{separator}')"
36
+ end
37
+
38
+ def time_zone_query_pre
39
+ ["SET TIME_ZONE = '+0:00'"]
40
+ end
41
+
42
+ def utf8_query_pre
43
+ ["SET NAMES #{settings['mysql_encoding']}"]
44
+ end
45
+
46
+ private
47
+
48
+ def settings
49
+ ThinkingSphinx::Configuration.instance.settings
50
+ end
51
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter <
4
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::AbstractAdapter
5
+
6
+ def boolean_value(value)
7
+ value ? 'TRUE' : 'FALSE'
8
+ end
9
+
10
+ def cast_to_bigint(clause)
11
+ "#{clause}::bigint"
12
+ end
13
+
14
+ def cast_to_string(clause)
15
+ "#{clause}::varchar"
16
+ end
17
+
18
+ def cast_to_timestamp(clause)
19
+ if ThinkingSphinx::Configuration.instance.settings['64bit_timestamps']
20
+ "extract(epoch from #{clause})::bigint"
21
+ else
22
+ "extract(epoch from #{clause})::int"
23
+ end
24
+ end
25
+
26
+ def concatenate(clause, separator = ' ')
27
+ clause.split(', ').collect { |part|
28
+ convert_nulls(part, "''")
29
+ }.join(" || '#{separator}' || ")
30
+ end
31
+
32
+ def convert_nulls(clause, default = '')
33
+ "COALESCE(#{clause}, #{default})"
34
+ end
35
+
36
+ def convert_blank(clause, default = '')
37
+ "COALESCE(NULLIF(#{clause}, ''), #{default})"
38
+ end
39
+
40
+ def group_concatenate(clause, separator = ' ')
41
+ "array_to_string(array_agg(DISTINCT #{clause}), '#{separator}')"
42
+ end
43
+
44
+ def time_zone_query_pre
45
+ ['SET TIME ZONE UTC']
46
+ end
47
+ end