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,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks do
6
+ let(:callbacks) {
7
+ ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks.new instance
8
+ }
9
+ let(:instance) { double('instance', :delta? => true) }
10
+
11
+ describe '.after_destroy' do
12
+ let(:callbacks) { double('callbacks', :after_destroy => nil) }
13
+
14
+ before :each do
15
+ allow(ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks).
16
+ to receive_messages :new => callbacks
17
+ end
18
+
19
+ it "builds an object from the instance" do
20
+ expect(ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks).
21
+ to receive(:new).with(instance).and_return(callbacks)
22
+
23
+ ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks.
24
+ after_destroy(instance)
25
+ end
26
+
27
+ it "invokes after_destroy on the object" do
28
+ expect(callbacks).to receive(:after_destroy)
29
+
30
+ ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks.
31
+ after_destroy(instance)
32
+ end
33
+ end
34
+
35
+ describe '#after_destroy' do
36
+ let(:index_set) { double 'index set', :to_a => [index] }
37
+ let(:index) { double('index', :name => 'foo_core', :primary_key => :id,
38
+ :document_id_for_key => 14, :type => 'plain', :distributed? => false) }
39
+ let(:instance) { double('instance', :id => 7, :new_record? => false) }
40
+
41
+ before :each do
42
+ allow(ThinkingSphinx::IndexSet).to receive_messages :new => index_set
43
+ end
44
+
45
+ it "performs the deletion for the index and instance" do
46
+ expect(ThinkingSphinx::Deletion).to receive(:perform).with(index, 7)
47
+
48
+ callbacks.after_destroy
49
+ end
50
+
51
+ it "doesn't do anything if the instance is a new record" do
52
+ allow(instance).to receive_messages :new_record? => true
53
+
54
+ expect(ThinkingSphinx::Deletion).not_to receive(:perform)
55
+
56
+ callbacks.after_destroy
57
+ end
58
+
59
+ it 'does nothing if callbacks are suspended' do
60
+ ThinkingSphinx::Callbacks.suspend!
61
+
62
+ expect(ThinkingSphinx::Deletion).not_to receive(:perform)
63
+
64
+ callbacks.after_destroy
65
+
66
+ ThinkingSphinx::Callbacks.resume!
67
+ end
68
+ end
69
+
70
+ describe '.after_rollback' do
71
+ let(:callbacks) { double('callbacks', :after_rollback => nil) }
72
+
73
+ before :each do
74
+ allow(ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks).
75
+ to receive_messages :new => callbacks
76
+ end
77
+
78
+ it "builds an object from the instance" do
79
+ expect(ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks).
80
+ to receive(:new).with(instance).and_return(callbacks)
81
+
82
+ ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks.
83
+ after_rollback(instance)
84
+ end
85
+
86
+ it "invokes after_rollback on the object" do
87
+ expect(callbacks).to receive(:after_rollback)
88
+
89
+ ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks.
90
+ after_rollback(instance)
91
+ end
92
+ end
93
+
94
+ describe '#after_rollback' do
95
+ let(:index_set) { double 'index set', :to_a => [index] }
96
+ let(:index) { double('index', :name => 'foo_core', :primary_key => :id,
97
+ :document_id_for_key => 14, :type => 'plain', :distributed? => false) }
98
+ let(:instance) { double('instance', :id => 7, :new_record? => false) }
99
+
100
+ before :each do
101
+ allow(ThinkingSphinx::IndexSet).to receive_messages :new => index_set
102
+ end
103
+
104
+ it "performs the deletion for the index and instance" do
105
+ expect(ThinkingSphinx::Deletion).to receive(:perform).with(index, 7)
106
+
107
+ callbacks.after_rollback
108
+ end
109
+
110
+ it "doesn't do anything if the instance is a new record" do
111
+ allow(instance).to receive_messages :new_record? => true
112
+
113
+ expect(ThinkingSphinx::Deletion).not_to receive(:perform)
114
+
115
+ callbacks.after_rollback
116
+ end
117
+
118
+ it 'does nothing if callbacks are suspended' do
119
+ ThinkingSphinx::Callbacks.suspend!
120
+
121
+ expect(ThinkingSphinx::Deletion).not_to receive(:perform)
122
+
123
+ callbacks.after_rollback
124
+
125
+ ThinkingSphinx::Callbacks.resume!
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,176 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks do
6
+ let(:callbacks) {
7
+ ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks.new instance
8
+ }
9
+ let(:instance) { double('instance', :delta? => true) }
10
+ let(:config) { double('config') }
11
+ let(:processor) {
12
+ double('processor', :toggled? => true, :index => true, :delete => true)
13
+ }
14
+
15
+ before :each do
16
+ allow(ThinkingSphinx::Configuration).to receive_messages :instance => config
17
+ end
18
+
19
+ [:after_commit, :before_save].each do |callback|
20
+ describe ".#{callback}" do
21
+ let(:callbacks) { double('callbacks', callback => nil) }
22
+
23
+ before :each do
24
+ allow(ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks).
25
+ to receive_messages :new => callbacks
26
+ end
27
+
28
+ it "builds an object from the instance" do
29
+ expect(ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks).
30
+ to receive(:new).with(instance).and_return(callbacks)
31
+
32
+ ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks.
33
+ send(callback, instance)
34
+ end
35
+
36
+ it "invokes #{callback} on the object" do
37
+ expect(callbacks).to receive(callback)
38
+
39
+ ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks.
40
+ send(callback, instance)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#after_commit' do
46
+ let(:index) {
47
+ double('index', :delta? => false, :delta_processor => processor,
48
+ :type => 'plain')
49
+ }
50
+
51
+ before :each do
52
+ allow(config).to receive_messages :index_set_class => double(:new => [index])
53
+ end
54
+
55
+ context 'without delta indices' do
56
+ it "does not fire a delta index when no delta indices" do
57
+ expect(processor).not_to receive(:index)
58
+
59
+ callbacks.after_commit
60
+ end
61
+
62
+ it "does not delete the instance from any index" do
63
+ expect(processor).not_to receive(:delete)
64
+
65
+ callbacks.after_commit
66
+ end
67
+ end
68
+
69
+ context 'with delta indices' do
70
+ let(:core_index) { double('index', :delta? => false, :name => 'foo_core',
71
+ :delta_processor => processor, :type => 'plain') }
72
+ let(:delta_index) { double('index', :delta? => true, :name => 'foo_delta',
73
+ :delta_processor => processor, :type => 'plain') }
74
+
75
+ before :each do
76
+ allow(ThinkingSphinx::Deltas).to receive_messages :suspended? => false
77
+
78
+ allow(config).to receive_messages :index_set_class => double(
79
+ :new => [core_index, delta_index]
80
+ )
81
+ end
82
+
83
+ it "only indexes delta indices" do
84
+ expect(processor).to receive(:index).with(delta_index)
85
+
86
+ callbacks.after_commit
87
+ end
88
+
89
+ it "does not process delta indices when deltas are suspended" do
90
+ allow(ThinkingSphinx::Deltas).to receive_messages :suspended? => true
91
+
92
+ expect(processor).not_to receive(:index)
93
+
94
+ callbacks.after_commit
95
+ end
96
+
97
+ it "deletes the instance from the core index" do
98
+ expect(processor).to receive(:delete).with(core_index, instance)
99
+
100
+ callbacks.after_commit
101
+ end
102
+
103
+ it "does not index if model's delta flag is not true" do
104
+ allow(processor).to receive_messages :toggled? => false
105
+
106
+ expect(processor).not_to receive(:index)
107
+
108
+ callbacks.after_commit
109
+ end
110
+
111
+ it "does not delete if model's delta flag is not true" do
112
+ allow(processor).to receive_messages :toggled? => false
113
+
114
+ expect(processor).not_to receive(:delete)
115
+
116
+ callbacks.after_commit
117
+ end
118
+
119
+ it "does not delete when deltas are suspended" do
120
+ allow(ThinkingSphinx::Deltas).to receive_messages :suspended? => true
121
+
122
+ expect(processor).not_to receive(:delete)
123
+
124
+ callbacks.after_commit
125
+ end
126
+ end
127
+ end
128
+
129
+ describe '#before_save' do
130
+ let(:index) {
131
+ double('index', :delta? => true, :delta_processor => processor,
132
+ :type => 'plain')
133
+ }
134
+
135
+ before :each do
136
+ allow(config).to receive_messages :index_set_class => double(:new => [index])
137
+ allow(instance).to receive_messages(
138
+ :changed? => true,
139
+ :new_record? => false
140
+ )
141
+ end
142
+
143
+ it "sets delta to true if there are delta indices" do
144
+ expect(processor).to receive(:toggle).with(instance)
145
+
146
+ callbacks.before_save
147
+ end
148
+
149
+ it "does not try to set delta to true if there are no delta indices" do
150
+ allow(index).to receive_messages :delta? => false
151
+
152
+ expect(processor).not_to receive(:toggle)
153
+
154
+ callbacks.before_save
155
+ end
156
+
157
+ it "does not try to set delta to true if the instance is unchanged" do
158
+ allow(instance).to receive_messages :changed? => false
159
+
160
+ expect(processor).not_to receive(:toggle)
161
+
162
+ callbacks.before_save
163
+ end
164
+
165
+ it "does set delta to true if the instance is unchanged but new" do
166
+ allow(instance).to receive_messages(
167
+ :changed? => false,
168
+ :new_record? => true
169
+ )
170
+
171
+ expect(processor).to receive(:toggle)
172
+
173
+ callbacks.before_save
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThinkingSphinx
4
+ module ActiveRecord
5
+ module Callbacks; end
6
+ end
7
+ end
8
+
9
+ require 'active_support/core_ext/string/inflections'
10
+ require 'thinking_sphinx/callbacks'
11
+ require 'thinking_sphinx/errors'
12
+ require 'thinking_sphinx/active_record/callbacks/update_callbacks'
13
+
14
+ describe ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks do
15
+ describe '#after_update' do
16
+ let(:callbacks) {
17
+ ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks.new instance }
18
+ let(:instance) { double('instance', :class => klass, :id => 2) }
19
+ let(:klass) { double(:name => 'Article') }
20
+ let(:configuration) { double('configuration',
21
+ :settings => {'attribute_updates' => true},
22
+ :indices_for_references => [index], :index_set_class => set_class) }
23
+ let(:connection) { double('connection', :execute => '') }
24
+ let(:index) { double 'index', :name => 'article_core',
25
+ :sources => [source], :document_id_for_key => 3, :distributed? => false,
26
+ :type => 'plain', :primary_key => :id}
27
+ let(:source) { double('source', :attributes => []) }
28
+ let(:set_class) { double(:reference_name => :article) }
29
+
30
+ before :each do
31
+ stub_const 'ThinkingSphinx::Configuration',
32
+ double(:instance => configuration)
33
+ stub_const 'ThinkingSphinx::Connection', double
34
+ stub_const 'Riddle::Query', double(:update => 'SphinxQL')
35
+
36
+ allow(ThinkingSphinx::Connection).to receive(:take).and_yield(connection)
37
+
38
+ source.attributes.replace([
39
+ double(:name => 'foo', :updateable? => true,
40
+ :columns => [double(:__name => 'foo_column')]),
41
+ double(:name => 'bar', :updateable? => true, :value_for => 7,
42
+ :columns => [double(:__name => 'bar_column')]),
43
+ double(:name => 'baz', :updateable? => false)
44
+ ])
45
+
46
+ allow(instance).to receive_messages(
47
+ :changed => ['bar_column', 'baz'],
48
+ :bar_column => 7,
49
+ :saved_changes => {'bar_column' => [1, 2], 'baz' => [3, 4]}
50
+ )
51
+ end
52
+
53
+ it "does not send any updates to Sphinx if updates are disabled" do
54
+ configuration.settings['attribute_updates'] = false
55
+
56
+ expect(connection).not_to receive(:execute)
57
+
58
+ callbacks.after_update
59
+ end
60
+
61
+ it "builds an update query with only updateable attributes that have changed" do
62
+ expect(Riddle::Query).to receive(:update).
63
+ with('article_core', 3, { 'bar' => 7 }).and_return('SphinxQL')
64
+
65
+ callbacks.after_update
66
+ end
67
+
68
+ it "sends the update query through to Sphinx" do
69
+ expect(connection).to receive(:execute).with('SphinxQL')
70
+
71
+ callbacks.after_update
72
+ end
73
+
74
+ it "doesn't care if the update fails at Sphinx's end" do
75
+ allow(connection).to receive(:execute).
76
+ and_raise(ThinkingSphinx::ConnectionError.new(''))
77
+
78
+ expect { callbacks.after_update }.not_to raise_error
79
+ end
80
+
81
+ it 'does nothing if callbacks are suspended' do
82
+ ThinkingSphinx::Callbacks.suspend!
83
+
84
+ expect(connection).not_to receive(:execute)
85
+
86
+ callbacks.after_update
87
+
88
+ ThinkingSphinx::Callbacks.resume!
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ThinkingSphinx::ActiveRecord::Column do
6
+ describe '#__name' do
7
+ it "returns the top item" do
8
+ column = ThinkingSphinx::ActiveRecord::Column.new(:content)
9
+ expect(column.__name).to eq(:content)
10
+ end
11
+ end
12
+
13
+ describe '#__replace' do
14
+ let(:base) { [:a, :b] }
15
+ let(:replacements) { [[:a, :c], [:a, :d]] }
16
+
17
+ it "returns itself when it's a string column" do
18
+ column = ThinkingSphinx::ActiveRecord::Column.new('foo')
19
+ expect(column.__replace(base, replacements).collect(&:__path)).
20
+ to eq([['foo']])
21
+ end
22
+
23
+ it "returns itself when the base of the stack does not match" do
24
+ column = ThinkingSphinx::ActiveRecord::Column.new(:b, :c)
25
+ expect(column.__replace(base, replacements).collect(&:__path)).
26
+ to eq([[:b, :c]])
27
+ end
28
+
29
+ it "returns an array of new columns " do
30
+ column = ThinkingSphinx::ActiveRecord::Column.new(:a, :b, :e)
31
+ expect(column.__replace(base, replacements).collect(&:__path)).
32
+ to eq([[:a, :c, :e], [:a, :d, :e]])
33
+ end
34
+ end
35
+
36
+ describe '#__stack' do
37
+ it "returns all but the top item" do
38
+ column = ThinkingSphinx::ActiveRecord::Column.new(:users, :posts, :id)
39
+ expect(column.__stack).to eq([:users, :posts])
40
+ end
41
+ end
42
+
43
+ describe '#method_missing' do
44
+ let(:column) { ThinkingSphinx::ActiveRecord::Column.new(:user) }
45
+
46
+ it "shifts the current name to the stack" do
47
+ column.email
48
+ expect(column.__stack).to eq([:user])
49
+ end
50
+
51
+ it "adds the new method call as the name" do
52
+ column.email
53
+ expect(column.__name).to eq(:email)
54
+ end
55
+
56
+ it "returns itself" do
57
+ expect(column.email).to eq(column)
58
+ end
59
+ end
60
+
61
+ describe '#string?' do
62
+ it "is true when the name is a string" do
63
+ column = ThinkingSphinx::ActiveRecord::Column.new('content')
64
+ expect(column).to be_a_string
65
+ end
66
+
67
+ it "is false when the name is a symbol" do
68
+ column = ThinkingSphinx::ActiveRecord::Column.new(:content)
69
+ expect(column).not_to be_a_string
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ThinkingSphinx::ActiveRecord::ColumnSQLPresenter do
6
+ describe '#with_table' do
7
+ let(:model) { double 'Model' }
8
+ let(:column) { double 'Column', :__name => 'column_name',
9
+ :__stack => [], :string? => false }
10
+ let(:adapter) { double 'Adapter' }
11
+ let(:associations) { double 'Associations' }
12
+ let(:path) { double 'Path',
13
+ :model => double(:column_names => ['column_name']) }
14
+ let(:presenter) { ThinkingSphinx::ActiveRecord::ColumnSQLPresenter.new(
15
+ model, column, adapter, associations
16
+ ) }
17
+
18
+ before do
19
+ stub_const 'Joiner::Path', double(:new => path)
20
+ allow(adapter).to receive(:quote) { |arg| "`#{arg}`" }
21
+ end
22
+
23
+ context "when there's no explicit db name" do
24
+ before { allow(associations).to receive_messages(:alias_for => 'table_name') }
25
+
26
+ it 'returns quoted table and column names' do
27
+ expect(presenter.with_table).to eq('`table_name`.`column_name`')
28
+ end
29
+ end
30
+
31
+ context 'when an eplicit db name is provided' do
32
+ before { allow(associations).to receive_messages(:alias_for => 'db_name.table_name') }
33
+
34
+ it 'returns properly quoted table name with column name' do
35
+ expect(presenter.with_table).to eq('`db_name`.`table_name`.`column_name`')
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ThinkingSphinx::ActiveRecord::DatabaseAdapters::AbstractAdapter do
6
+ let(:adapter) {
7
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::AbstractAdapter.new model
8
+ }
9
+ let(:model) { double('model', :connection => connection) }
10
+ let(:connection) { double('connection') }
11
+
12
+ describe '#quote' do
13
+ it "uses the model's connection to quote columns" do
14
+ expect(connection).to receive(:quote_column_name).with('foo')
15
+
16
+ adapter.quote 'foo'
17
+ end
18
+
19
+ it "returns the quoted value" do
20
+ allow(connection).to receive_messages :quote_column_name => '"foo"'
21
+
22
+ expect(adapter.quote('foo')).to eq('"foo"')
23
+ end
24
+ end
25
+
26
+ describe '#quoted_table_name' do
27
+ it "passes the method through to the model" do
28
+ expect(model).to receive(:quoted_table_name).and_return('"articles"')
29
+
30
+ expect(adapter.quoted_table_name).to eq('"articles"')
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter do
6
+ let(:adapter) {
7
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::MySQLAdapter.new(model)
8
+ }
9
+ let(:model) { double('model') }
10
+
11
+ it "returns 1 for true" do
12
+ expect(adapter.boolean_value(true)).to eq(1)
13
+ end
14
+
15
+ it "returns 0 for false" do
16
+ expect(adapter.boolean_value(false)).to eq(0)
17
+ end
18
+
19
+ describe '#cast_to_string' do
20
+ it "casts the clause to characters" do
21
+ expect(adapter.cast_to_string('foo')).to eq("CAST(foo AS char)")
22
+ end
23
+ end
24
+
25
+ describe '#cast_to_timestamp' do
26
+ it "converts to unix timestamps" do
27
+ expect(adapter.cast_to_timestamp('created_at')).
28
+ to eq('UNIX_TIMESTAMP(created_at)')
29
+ end
30
+ end
31
+
32
+ describe '#concatenate' do
33
+ it "concatenates with the given separator" do
34
+ expect(adapter.concatenate('foo, bar, baz', ',')).
35
+ to eq("CONCAT_WS(',', foo, bar, baz)")
36
+ end
37
+ end
38
+
39
+ describe '#convert_nulls' do
40
+ it "translates arguments to an IFNULL SQL call" do
41
+ expect(adapter.convert_nulls('id', 5)).to eq('IFNULL(id, 5)')
42
+ end
43
+ end
44
+
45
+ describe '#convert_blank' do
46
+ it "translates arguments to a COALESCE NULLIF SQL call" do
47
+ expect(adapter.convert_blank('id', 5)).to eq("COALESCE(NULLIF(id, ''), 5)")
48
+ end
49
+ end
50
+
51
+ describe '#group_concatenate' do
52
+ it "group concatenates the clause with the given separator" do
53
+ expect(adapter.group_concatenate('foo', ',')).
54
+ to eq("GROUP_CONCAT(DISTINCT foo SEPARATOR ',')")
55
+ end
56
+ end
57
+
58
+ describe '#utf8_query_pre' do
59
+ it "defaults to using utf8" do
60
+ expect(adapter.utf8_query_pre).to eq(["SET NAMES utf8"])
61
+ end
62
+
63
+ it "allows custom values" do
64
+ ThinkingSphinx::Configuration.instance.settings['mysql_encoding'] =
65
+ 'utf8mb4'
66
+
67
+ expect(adapter.utf8_query_pre).to eq(["SET NAMES utf8mb4"])
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter do
6
+ let(:adapter) {
7
+ ThinkingSphinx::ActiveRecord::DatabaseAdapters::PostgreSQLAdapter.new(model)
8
+ }
9
+ let(:model) { double('model') }
10
+
11
+ describe '#boolean_value' do
12
+ it "returns 'TRUE' for true" do
13
+ expect(adapter.boolean_value(true)).to eq('TRUE')
14
+ end
15
+
16
+ it "returns 'FALSE' for false" do
17
+ expect(adapter.boolean_value(false)).to eq('FALSE')
18
+ end
19
+ end
20
+
21
+ describe '#cast_to_string' do
22
+ it "casts the clause to characters" do
23
+ expect(adapter.cast_to_string('foo')).to eq('foo::varchar')
24
+ end
25
+ end
26
+
27
+ describe '#cast_to_timestamp' do
28
+ it "converts to int unix timestamps" do
29
+ expect(adapter.cast_to_timestamp('created_at')).
30
+ to eq('extract(epoch from created_at)::int')
31
+ end
32
+
33
+ it "converts to bigint unix timestamps" do
34
+ ThinkingSphinx::Configuration.instance.settings['64bit_timestamps'] = true
35
+
36
+ expect(adapter.cast_to_timestamp('created_at')).
37
+ to eq('extract(epoch from created_at)::bigint')
38
+ end
39
+ end
40
+
41
+ describe '#concatenate' do
42
+ it "concatenates with the given separator" do
43
+ expect(adapter.concatenate('foo, bar, baz', ',')).
44
+ to eq("COALESCE(foo, '') || ',' || COALESCE(bar, '') || ',' || COALESCE(baz, '')")
45
+ end
46
+ end
47
+
48
+ describe '#convert_nulls' do
49
+ it "translates arguments to a COALESCE SQL call" do
50
+ expect(adapter.convert_nulls('id', 5)).to eq('COALESCE(id, 5)')
51
+ end
52
+ end
53
+
54
+ describe '#convert_blank' do
55
+ it "translates arguments to a COALESCE NULLIF SQL call" do
56
+ expect(adapter.convert_blank('id', 5)).to eq("COALESCE(NULLIF(id, ''), 5)")
57
+ end
58
+ end
59
+
60
+ describe '#group_concatenate' do
61
+ it "group concatenates the clause with the given separator" do
62
+ expect(adapter.group_concatenate('foo', ',')).
63
+ to eq("array_to_string(array_agg(DISTINCT foo), ',')")
64
+ end
65
+ end
66
+ end