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,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Updates to records in real-time indices', :live => true do
6
+ it "handles fields with unicode nulls" do
7
+ product = Product.create! :name => "Widget \u0000"
8
+
9
+ expect(Product.search.first).to eq(product)
10
+ end unless ENV['DATABASE'] == 'postgresql'
11
+
12
+ it "handles attributes for sortable fields accordingly" do
13
+ product = Product.create! :name => 'Red Fish'
14
+ product.update :name => 'Blue Fish'
15
+
16
+ expect(Product.search('blue fish', :indices => ['product_core']).to_a).
17
+ to eq([product])
18
+ end
19
+
20
+ it "handles inserts and updates for namespaced models" do
21
+ person = Admin::Person.create :name => 'Death'
22
+
23
+ expect(Admin::Person.search('Death').to_a).to eq([person])
24
+
25
+ person.update :name => 'Mort'
26
+
27
+ expect(Admin::Person.search('Death').to_a).to be_empty
28
+ expect(Admin::Person.search('Mort').to_a).to eq([person])
29
+ end
30
+
31
+ it "can use direct interface for upserting records" do
32
+ Admin::Person.connection.execute <<~SQL
33
+ INSERT INTO admin_people (name, created_at, updated_at)
34
+ VALUES ('Pat', now(), now());
35
+ SQL
36
+
37
+ expect(Admin::Person.search('Pat').to_a).to be_empty
38
+
39
+ instance = Admin::Person.find_by(:name => 'Pat')
40
+ ThinkingSphinx::Processor.new(instance: instance).upsert
41
+
42
+ expect(Admin::Person.search('Pat').to_a).to eq([instance])
43
+
44
+ Admin::Person.connection.execute <<~SQL
45
+ UPDATE admin_people SET name = 'Patrick' WHERE name = 'Pat';
46
+ SQL
47
+
48
+ expect(Admin::Person.search('Patrick').to_a).to be_empty
49
+
50
+ instance.reload
51
+ ThinkingSphinx::Processor.new(model: Admin::Person, id: instance.id).upsert
52
+
53
+ expect(Admin::Person.search('Patrick').to_a).to eq([instance])
54
+ end
55
+
56
+ it "can use direct interface for processing records outside scope" do
57
+ Article.connection.execute <<~SQL
58
+ INSERT INTO articles (title, published, created_at, updated_at)
59
+ VALUES ('Nice Title', TRUE, now(), now());
60
+ SQL
61
+
62
+ article = Article.last
63
+
64
+ ThinkingSphinx::Processor.new(model: article.class, id: article.id).sync
65
+
66
+ expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article)
67
+
68
+ Article.connection.execute <<~SQL
69
+ UPDATE articles SET published = FALSE WHERE title = 'Nice Title';
70
+ SQL
71
+ ThinkingSphinx::Processor.new(model: article.class, id: article.id).sync
72
+
73
+ expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty
74
+ end
75
+
76
+ it "can use direct interface for processing deleted records" do
77
+ Article.connection.execute <<~SQL
78
+ INSERT INTO articles (title, published, created_at, updated_at)
79
+ VALUES ('Nice Title', TRUE, now(), now());
80
+ SQL
81
+
82
+ article = Article.last
83
+ ThinkingSphinx::Processor.new(:instance => article).sync
84
+
85
+ expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to include(article)
86
+
87
+ Article.connection.execute <<~SQL
88
+ DELETE FROM articles where title = 'Nice Title';
89
+ SQL
90
+
91
+ ThinkingSphinx::Processor.new(:instance => article).sync
92
+
93
+ expect(ThinkingSphinx.search('Nice', :indices => ["published_articles_core"])).to be_empty
94
+ end
95
+
96
+ it "syncs records in real-time index with alternate ids" do
97
+ Album.connection.execute <<~SQL
98
+ INSERT INTO albums (id, name, artist, integer_id)
99
+ VALUES ('#{("a".."z").to_a.sample}', 'Sing to the Moon', 'Laura Mvula', #{rand(10000)});
100
+ SQL
101
+
102
+ album = Album.last
103
+ ThinkingSphinx::Processor.new(:model => Album, id: album.integer_id).sync
104
+
105
+ expect(ThinkingSphinx.search('Laura', :indices => ["album_real_core"])).to include(album)
106
+
107
+ Article.connection.execute <<~SQL
108
+ DELETE FROM albums where id = '#{album.id}';
109
+ SQL
110
+
111
+ ThinkingSphinx::Processor.new(:instance => album).sync
112
+
113
+ expect(ThinkingSphinx.search('Laura', :indices => ["album_real_core"])).to be_empty
114
+ end
115
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Hiding deleted records from search results', :live => true do
6
+ it "does not return deleted records" do
7
+ pancakes = Article.create! :title => 'Pancakes'
8
+ index
9
+
10
+ expect(Article.search('pancakes')).not_to be_empty
11
+ pancakes.destroy
12
+
13
+ expect(Article.search('pancakes')).to be_empty
14
+ end
15
+
16
+ it "will catch stale records deleted without callbacks being fired" do
17
+ pancakes = Article.create! :title => 'Pancakes'
18
+ index
19
+
20
+ expect(Article.search('pancakes')).not_to be_empty
21
+ Article.connection.execute "DELETE FROM articles WHERE id = #{pancakes.id}"
22
+
23
+ expect(Article.search('pancakes')).to be_empty
24
+ end
25
+
26
+ it "removes records from real-time index results" do
27
+ product = Product.create! :name => 'Shiny'
28
+
29
+ expect(Product.search('Shiny', :indices => ['product_core']).to_a).
30
+ to eq([product])
31
+
32
+ product.destroy
33
+
34
+ expect(Product.search_for_ids('Shiny', :indices => ['product_core'])).
35
+ to be_empty
36
+ end
37
+
38
+ it "removes records from real-time index results with alternate ids" do
39
+ album = Album.create! :name => 'Sing to the Moon', :artist => 'Laura Mvula'
40
+
41
+ expect(Album.search('Sing', :indices => ['album_real_core']).to_a).
42
+ to eq([album])
43
+
44
+ album.destroy
45
+
46
+ expect(Album.search_for_ids('Sing', :indices => ['album_real_core'])).
47
+ to be_empty
48
+ end
49
+
50
+ it "does not remove real-time results when callbacks are disabled" do
51
+ original = ThinkingSphinx::Configuration.instance.
52
+ settings['real_time_callbacks']
53
+ product = Product.create! :name => 'Shiny'
54
+ expect(Product.search('Shiny', :indices => ['product_core']).to_a).
55
+ to eq([product])
56
+
57
+ ThinkingSphinx::Configuration.instance.
58
+ settings['real_time_callbacks'] = false
59
+
60
+ product.destroy
61
+ expect(Product.search_for_ids('Shiny', :indices => ['product_core'])).
62
+ not_to be_empty
63
+
64
+ ThinkingSphinx::Configuration.instance.
65
+ settings['real_time_callbacks'] = original
66
+ end
67
+
68
+ it "deletes STI child classes from parent indices" do
69
+ duck = Bird.create :name => 'Duck'
70
+ index
71
+ duck.destroy
72
+
73
+ expect(Bird.search_for_ids('duck')).to be_empty
74
+ end
75
+
76
+ it "can use a direct interface for processing records" do
77
+ pancakes = Article.create! :title => 'Pancakes'
78
+ index
79
+ expect(Article.search('pancakes')).not_to be_empty
80
+
81
+ Article.connection.execute "DELETE FROM articles WHERE id = #{pancakes.id}"
82
+ expect(Article.search_for_ids('pancakes')).not_to be_empty
83
+
84
+ ThinkingSphinx::Processor.new(instance: pancakes).delete
85
+ expect(Article.search_for_ids('pancakes')).to be_empty
86
+ end
87
+
88
+ it "can use a direct interface for processing records without an instance" do
89
+ pancakes = Article.create! :title => 'Pancakes'
90
+ index
91
+ expect(Article.search('pancakes')).not_to be_empty
92
+
93
+ Article.connection.execute "DELETE FROM articles WHERE id = #{pancakes.id}"
94
+ expect(Article.search_for_ids('pancakes')).not_to be_empty
95
+
96
+ ThinkingSphinx::Processor.new(model: Article, id: pancakes.id).delete
97
+ expect(Article.search_for_ids('pancakes')).to be_empty
98
+ end
99
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Get search result counts', :live => true do
6
+ it "returns counts for a single model" do
7
+ 4.times { |i| Article.create :title => "Article #{i}" }
8
+ index
9
+
10
+ expect(Article.search_count).to eq(4)
11
+ end
12
+
13
+ it "returns counts across all models" do
14
+ 3.times { |i| Article.create :title => "Article #{i}" }
15
+ 2.times { |i| Book.create :title => "Book #{i}" }
16
+ index
17
+
18
+ expect(ThinkingSphinx.count).to eq(5)
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Searching for just instance Ids', :live => true do
6
+ it "returns just the instance ids" do
7
+ pancakes = Article.create! :title => 'Pancakes'
8
+ waffles = Article.create! :title => 'Waffles'
9
+ index
10
+
11
+ expect(Article.search_for_ids('pancakes').to_a).to eq([pancakes.id])
12
+ end
13
+
14
+ it "works across the global context" do
15
+ article = Article.create! :title => 'Pancakes'
16
+ book = Book.create! :title => 'American Gods'
17
+ index
18
+
19
+ expect(ThinkingSphinx.search_for_ids.to_a).to match_array([article.id, book.id])
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Searching across models', :live => true do
6
+ it "returns results" do
7
+ article = Article.create! :title => 'Pancakes'
8
+ index
9
+
10
+ expect(ThinkingSphinx.search.first).to eq(article)
11
+ end
12
+
13
+ it "returns results matching the given query" do
14
+ pancakes = Article.create! :title => 'Pancakes'
15
+ waffles = Article.create! :title => 'Waffles'
16
+ index
17
+
18
+ articles = ThinkingSphinx.search 'pancakes'
19
+ expect(articles).to include(pancakes)
20
+ expect(articles).not_to include(waffles)
21
+ end
22
+
23
+ it "handles results from different models" do
24
+ article = Article.create! :title => 'Pancakes'
25
+ book = Book.create! :title => 'American Gods'
26
+ index
27
+
28
+ expect(ThinkingSphinx.search.to_a).to match_array([article, book])
29
+ end
30
+
31
+ it "filters by multiple classes" do
32
+ article = Article.create! :title => 'Pancakes'
33
+ book = Book.create! :title => 'American Gods'
34
+ user = User.create! :name => 'Pat'
35
+ index
36
+
37
+ expect(ThinkingSphinx.search(:classes => [User, Article]).to_a).
38
+ to match_array([article, user])
39
+ end
40
+
41
+ it "has a 'none' default scope" do
42
+ article = Article.create! :title => 'Pancakes'
43
+ index
44
+
45
+ expect(ThinkingSphinx.none).to be_empty
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ multi_schema = MultiSchema.new
6
+
7
+ describe 'Searching across PostgreSQL schemas', :live => true do
8
+ before :each do
9
+ ThinkingSphinx::Configuration.instance.index_set_class =
10
+ MultiSchema::IndexSet
11
+ end
12
+
13
+ after :each do
14
+ ThinkingSphinx::Configuration.instance.index_set_class = nil
15
+ multi_schema.switch :public
16
+ end
17
+
18
+ it 'can distinguish between objects with the same primary key' do
19
+ multi_schema.switch :public
20
+ jekyll = Product.create name: 'Doctor Jekyll'
21
+ expect(Product.search('Jekyll', :retry_stale => false).to_a).to eq([jekyll])
22
+ expect(Product.search(:retry_stale => false).to_a).to eq([jekyll])
23
+
24
+ multi_schema.switch :thinking_sphinx
25
+ hyde = Product.create name: 'Mister Hyde'
26
+ expect(Product.search('Jekyll', :retry_stale => false).to_a).to eq([])
27
+ expect(Product.search('Hyde', :retry_stale => false).to_a).to eq([hyde])
28
+ expect(Product.search(:retry_stale => false).to_a).to eq([hyde])
29
+
30
+ multi_schema.switch :public
31
+ expect(Product.search('Jekyll', :retry_stale => false).to_a).to eq([jekyll])
32
+ expect(Product.search(:retry_stale => false).to_a).to eq([jekyll])
33
+ expect(Product.search('Hyde', :retry_stale => false).to_a).to eq([])
34
+
35
+ expect(Product.search(
36
+ :middleware => ThinkingSphinx::Middlewares::RAW_ONLY,
37
+ :indices => ['product_core', 'product_two_core']
38
+ ).to_a.length).to eq(2)
39
+ end
40
+ end if multi_schema.active?
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Searching on fields', :live => true do
6
+ it "limits results by field" do
7
+ pancakes = Article.create! :title => 'Pancakes'
8
+ waffles = Article.create! :title => 'Waffles',
9
+ :content => 'Different to pancakes - and not quite as tasty.'
10
+ index
11
+
12
+ articles = Article.search :conditions => {:title => 'pancakes'}
13
+ expect(articles).to include(pancakes)
14
+ expect(articles).not_to include(waffles)
15
+ end
16
+
17
+ it "limits results for a field from an association" do
18
+ user = User.create! :name => 'Pat'
19
+ pancakes = Article.create! :title => 'Pancakes', :user => user
20
+ index
21
+
22
+ expect(Article.search(:conditions => {:user => 'pat'}).first).to eq(pancakes)
23
+ end
24
+
25
+ it "returns results with matches from grouped fields" do
26
+ user = User.create! :name => 'Pat'
27
+ pancakes = Article.create! :title => 'Pancakes', :user => user
28
+ waffles = Article.create! :title => 'Waffles', :user => user
29
+ index
30
+
31
+ expect(Article.search('waffles', :conditions => {:title => 'pancakes'}).to_a).
32
+ to eq([pancakes])
33
+ end
34
+
35
+ it "returns results with matches from concatenated columns in a field" do
36
+ book = Book.create! :title => 'Night Watch', :author => 'Terry Pratchett'
37
+ index
38
+
39
+ expect(Book.search(:conditions => {:info => 'Night Pratchett'}).to_a).
40
+ to eq([book])
41
+ end
42
+
43
+ it "handles NULLs in concatenated fields" do
44
+ book = Book.create! :title => 'Night Watch'
45
+ index
46
+
47
+ expect(Book.search(:conditions => {:info => 'Night Watch'}).to_a).to eq([book])
48
+ end
49
+
50
+ it "returns results with matches from file fields" do
51
+ file_path = Rails.root.join('tmp', 'caption.txt')
52
+ File.open(file_path, 'w') { |file| file.print 'Cyberpunk at its best' }
53
+
54
+ book = Book.create! :title => 'Accelerando', :blurb_file => file_path.to_s
55
+ index
56
+
57
+ expect(Book.search('cyberpunk').to_a).to eq([book])
58
+ end
59
+ end
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Searching with filters', :live => true do
6
+ it "limits results by single value boolean filters" do
7
+ pancakes = Article.create! :title => 'Pancakes', :published => true
8
+ waffles = Article.create! :title => 'Waffles', :published => false
9
+ index
10
+
11
+ expect(Article.search(:with => {:published => true}).to_a).to eq([pancakes])
12
+ end
13
+
14
+ it "limits results by an array of values" do
15
+ gods = Book.create! :title => 'American Gods', :publishing_year => 2001
16
+ boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005
17
+ grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009
18
+ index
19
+
20
+ expect(Book.search(:with => {:publishing_year => [2001, 2005]}).to_a).to match_array([gods, boys])
21
+ end
22
+
23
+ it "limits results by a ranged filter" do
24
+ gods = Book.create! :title => 'American Gods'
25
+ boys = Book.create! :title => 'Anansi Boys'
26
+ grave = Book.create! :title => 'The Graveyard Book'
27
+
28
+ gods.update_column :created_at, 5.days.ago
29
+ boys.update_column :created_at, 3.days.ago
30
+ grave.update_column :created_at, 1.day.ago
31
+ index
32
+
33
+ expect(Book.search(:with => {:created_at => 6.days.ago..2.days.ago}).to_a).
34
+ to match_array([gods, boys])
35
+ end
36
+
37
+ it "limits results by exclusive filters on single values" do
38
+ pancakes = Article.create! :title => 'Pancakes', :published => true
39
+ waffles = Article.create! :title => 'Waffles', :published => false
40
+ index
41
+
42
+ expect(Article.search(:without => {:published => true}).to_a).to eq([waffles])
43
+ end
44
+
45
+ it "limits results by exclusive filters on arrays of values" do
46
+ gods = Book.create! :title => 'American Gods', :publishing_year => 2001
47
+ boys = Book.create! :title => 'Anansi Boys', :publishing_year => 2005
48
+ grave = Book.create! :title => 'The Graveyard Book', :publishing_year => 2009
49
+ index
50
+
51
+ expect(Book.search(:without => {:publishing_year => [2001, 2005]}).to_a).to eq([grave])
52
+ end
53
+
54
+ it "limits results by ranged filters on timestamp MVAs" do
55
+ pancakes = Article.create :title => 'Pancakes'
56
+ waffles = Article.create :title => 'Waffles'
57
+
58
+ food = Tag.create :name => 'food'
59
+ flat = Tag.create :name => 'flat'
60
+
61
+ Tagging.create(:tag => food, :article => pancakes).
62
+ update_column :created_at, 5.days.ago
63
+ Tagging.create :tag => flat, :article => pancakes
64
+ Tagging.create(:tag => food, :article => waffles).
65
+ update_column :created_at, 3.days.ago
66
+
67
+ index
68
+
69
+ expect(Article.search(
70
+ :with => {:taggings_at => 1.days.ago..1.day.from_now}
71
+ ).to_a).to eq([pancakes])
72
+ end
73
+
74
+ it "takes into account local timezones for timestamps" do
75
+ pancakes = Article.create :title => 'Pancakes'
76
+ waffles = Article.create :title => 'Waffles'
77
+
78
+ food = Tag.create :name => 'food'
79
+ flat = Tag.create :name => 'flat'
80
+
81
+ Tagging.create(:tag => food, :article => pancakes).
82
+ update_column :created_at, 5.minutes.ago
83
+ Tagging.create :tag => flat, :article => pancakes
84
+ Tagging.create(:tag => food, :article => waffles).
85
+ update_column :created_at, 3.minute.ago
86
+
87
+ index
88
+
89
+ expect(Article.search(
90
+ :with => {:taggings_at => 2.minutes.ago..Time.zone.now}
91
+ ).to_a).to eq([pancakes])
92
+ end
93
+
94
+ it "limits results with MVAs having all of the given values" do
95
+ pancakes = Article.create :title => 'Pancakes'
96
+ waffles = Article.create :title => 'Waffles'
97
+
98
+ food = Tag.create :name => 'food'
99
+ flat = Tag.create :name => 'flat'
100
+
101
+ Tagging.create :tag => food, :article => pancakes
102
+ Tagging.create :tag => flat, :article => pancakes
103
+ Tagging.create :tag => food, :article => waffles
104
+
105
+ index
106
+
107
+ articles = Article.search :with_all => {:tag_ids => [food.id, flat.id]}
108
+ expect(articles.to_a).to eq([pancakes])
109
+ end
110
+
111
+ it "limits results with MVAs that don't contain all the given values" do
112
+ # Matching results may have some of the given values, but cannot have all
113
+ # of them. Certainly an edge case.
114
+ skip "SphinxQL doesn't yet support OR in its WHERE clause"
115
+
116
+ pancakes = Article.create :title => 'Pancakes'
117
+ waffles = Article.create :title => 'Waffles'
118
+
119
+ food = Tag.create :name => 'food'
120
+ flat = Tag.create :name => 'flat'
121
+
122
+ Tagging.create :tag => food, :article => pancakes
123
+ Tagging.create :tag => flat, :article => pancakes
124
+ Tagging.create :tag => food, :article => waffles
125
+
126
+ index
127
+
128
+ articles = Article.search :without_all => {:tag_ids => [food.id, flat.id]}
129
+ expect(articles.to_a).to eq([waffles])
130
+ end
131
+
132
+ it "limits results on real-time indices with multi-value integer attributes" do
133
+ pancakes = Product.create :name => 'Pancakes'
134
+ waffles = Product.create :name => 'Waffles'
135
+
136
+ food = Category.create :name => 'food'
137
+ flat = Category.create :name => 'flat'
138
+
139
+ pancakes.categories << food
140
+ pancakes.categories << flat
141
+ waffles.categories << food
142
+
143
+ products = Product.search :with => {:category_ids => [flat.id]}
144
+ expect(products.to_a).to eq([pancakes])
145
+ end
146
+
147
+ it 'searches with real-time JSON attributes' do
148
+ pancakes = Product.create :name => 'Pancakes',
149
+ :options => {'lemon' => 1, 'sugar' => 1, :number => 3}
150
+ waffles = Product.create :name => 'Waffles',
151
+ :options => {'chocolate' => 1, 'sugar' => 1, :number => 1}
152
+
153
+ products = Product.search :with => {"options.lemon" => 1}
154
+ expect(products.to_a).to eq([pancakes])
155
+
156
+ products = Product.search :with => {"options.sugar" => 1}
157
+ expect(products.to_a).to match_array([pancakes, waffles])
158
+ end if JSONColumn.call
159
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'acceptance/spec_helper'
4
+
5
+ describe 'Searching across STI models', :live => true do
6
+ it "returns super- and sub-class results" do
7
+ platypus = Animal.create :name => 'Platypus'
8
+ duck = Bird.create :name => 'Duck'
9
+ index
10
+
11
+ expect(Animal.search(:indices => ['animal_core']).to_a).to eq([platypus, duck])
12
+ end
13
+
14
+ it "limits results based on subclasses" do
15
+ platypus = Animal.create :name => 'Platypus'
16
+ duck = Bird.create :name => 'Duck'
17
+ index
18
+
19
+ expect(Bird.search(:indices => ['animal_core']).to_a).to eq([duck])
20
+ end
21
+
22
+ it "returns results for deeper subclasses when searching on their parents" do
23
+ platypus = Animal.create :name => 'Platypus'
24
+ duck = Bird.create :name => 'Duck'
25
+ emu = FlightlessBird.create :name => 'Emu'
26
+ index
27
+
28
+ expect(Bird.search(:indices => ['animal_core']).to_a).to eq([duck, emu])
29
+ end
30
+
31
+ it "returns results for deeper subclasses" do
32
+ platypus = Animal.create :name => 'Platypus'
33
+ duck = Bird.create :name => 'Duck'
34
+ emu = FlightlessBird.create :name => 'Emu'
35
+ index
36
+
37
+ expect(FlightlessBird.search(:indices => ['animal_core']).to_a).to eq([emu])
38
+ end
39
+
40
+ it "filters out sibling subclasses" do
41
+ platypus = Animal.create :name => 'Platypus'
42
+ duck = Bird.create :name => 'Duck'
43
+ otter = Mammal.create :name => 'Otter'
44
+ index
45
+
46
+ expect(Bird.search(:indices => ['animal_core']).to_a).to eq([duck])
47
+ end
48
+
49
+ it "obeys :classes if supplied" do
50
+ platypus = Animal.create :name => 'Platypus'
51
+ duck = Bird.create :name => 'Duck'
52
+ emu = FlightlessBird.create :name => 'Emu'
53
+ index
54
+
55
+ expect(Bird.search(
56
+ :indices => ['animal_core'],
57
+ :skip_sti => true,
58
+ :classes => [Bird, FlightlessBird]
59
+ ).to_a).to eq([duck, emu])
60
+ end
61
+
62
+ it 'finds root objects when type is blank' do
63
+ animal = Animal.create :name => 'Animal', type: ''
64
+ index
65
+
66
+ expect(Animal.search(:indices => ['animal_core']).to_a).to eq([animal])
67
+ end
68
+
69
+ it 'allows for indices on mid-hierarchy classes' do
70
+ duck = Bird.create :name => 'Duck'
71
+ emu = FlightlessBird.create :name => 'Emu'
72
+ index
73
+
74
+ expect(Bird.search(:indices => ['bird_core']).to_a).to eq([duck, emu])
75
+ end
76
+ end