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
@@ -1,82 +0,0 @@
1
- module ThinkingSphinx
2
- # Fields - holding the string data which Sphinx indexes for your searches.
3
- # This class isn't really useful to you unless you're hacking around with the
4
- # internals of Thinking Sphinx - but hey, don't let that stop you.
5
- #
6
- # One key thing to remember - if you're using the field manually to
7
- # generate SQL statements, you'll need to set the base model, and all the
8
- # associations. Which can get messy. Use Index.link!, it really helps.
9
- #
10
- class Field < ThinkingSphinx::Property
11
- attr_accessor :sortable, :infixes, :prefixes
12
-
13
- # To create a new field, you'll need to pass in either a single Column
14
- # or an array of them, and some (optional) options. The columns are
15
- # references to the data that will make up the field.
16
- #
17
- # Valid options are:
18
- # - :as => :alias_name
19
- # - :sortable => true
20
- # - :infixes => true
21
- # - :prefixes => true
22
- #
23
- # Alias is only required in three circumstances: when there's
24
- # another attribute or field with the same name, when the column name is
25
- # 'id', or when there's more than one column.
26
- #
27
- # Sortable defaults to false - but is quite useful when set to true, as
28
- # it creates an attribute with the same string value (which Sphinx converts
29
- # to an integer value), which can be sorted by. Thinking Sphinx is smart
30
- # enough to realise that when you specify fields in sort statements, you
31
- # mean their respective attributes.
32
- #
33
- # If you have partial matching enabled (ie: enable_star), then you can
34
- # specify certain fields to have their prefixes and infixes indexed. Keep
35
- # in mind, though, that Sphinx's default is _all_ fields - so once you
36
- # highlight a particular field, no other fields in the index will have
37
- # these partial indexes.
38
- #
39
- # Here's some examples:
40
- #
41
- # Field.new(
42
- # Column.new(:name)
43
- # )
44
- #
45
- # Field.new(
46
- # [Column.new(:first_name), Column.new(:last_name)],
47
- # :as => :name, :sortable => true
48
- # )
49
- #
50
- # Field.new(
51
- # [Column.new(:posts, :subject), Column.new(:posts, :content)],
52
- # :as => :posts, :prefixes => true
53
- # )
54
- #
55
- def initialize(source, columns, options = {})
56
- super
57
-
58
- @sortable = options[:sortable] || false
59
- @infixes = options[:infixes] || false
60
- @prefixes = options[:prefixes] || false
61
-
62
- source.fields << self
63
- end
64
-
65
- # Get the part of the SELECT clause related to this field. Don't forget
66
- # to set your model and associations first though.
67
- #
68
- # This will concatenate strings if there's more than one data source or
69
- # multiple data values (has_many or has_and_belongs_to_many associations).
70
- #
71
- def to_select_sql
72
- clause = @columns.collect { |column|
73
- column_with_prefix(column)
74
- }.join(', ')
75
-
76
- clause = adapter.concatenate(clause) if concat_ws?
77
- clause = adapter.group_concatenate(clause) if is_many?
78
-
79
- "#{adapter.cast_to_string clause } AS #{quote_column(unique_name)}"
80
- end
81
- end
82
- end
@@ -1,286 +0,0 @@
1
- module ThinkingSphinx
2
- class Index
3
- # The Builder class is the core for the index definition block processing.
4
- # There are four methods you really need to pay attention to:
5
- # - indexes
6
- # - has
7
- # - where
8
- # - set_property/set_properties
9
- #
10
- # The first two of these methods allow you to define what data makes up
11
- # your indexes. #where provides a method to add manual SQL conditions, and
12
- # set_property allows you to set some settings on a per-index basis. Check
13
- # out each method's documentation for better ideas of usage.
14
- #
15
- class Builder
16
- instance_methods.grep(/^[^_]/).each { |method|
17
- next if method.to_s == "instance_eval"
18
- define_method(method) {
19
- caller.grep(/irb.completion/).empty? ? method_missing(method) : super
20
- }
21
- }
22
-
23
- def self.generate(model, &block)
24
- index = ThinkingSphinx::Index.new(model)
25
- model.sphinx_facets ||= []
26
-
27
- Builder.new(index, &block) if block_given?
28
-
29
- index.delta_object = ThinkingSphinx::Deltas.parse index
30
- index
31
- end
32
-
33
- def initialize(index, &block)
34
- @index = index
35
- @source = ThinkingSphinx::Source.new(@index)
36
- @index.sources << @source
37
- @explicit_source = false
38
-
39
- self.instance_eval &block
40
-
41
- if @index.sources.any? { |source|
42
- source.fields.length == 0
43
- }
44
- raise "At least one field is necessary for an index"
45
- end
46
- end
47
-
48
- def define_source(&block)
49
- if @explicit_source
50
- @source = ThinkingSphinx::Source.new(@index)
51
- @index.sources << @source
52
- else
53
- @explicit_source = true
54
- end
55
-
56
- self.instance_eval &block
57
- end
58
-
59
- # This is how you add fields - the strings Sphinx looks at - to your
60
- # index. Technically, to use this method, you need to pass in some
61
- # columns and options - but there's some neat method_missing stuff
62
- # happening, so lets stick to the expected syntax within a define_index
63
- # block.
64
- #
65
- # Expected options are :as, which points to a column alias in symbol
66
- # form, and :sortable, which indicates whether you want to sort by this
67
- # field.
68
- #
69
- # Adding Single-Column Fields:
70
- #
71
- # You can use symbols or methods - and can chain methods together to
72
- # get access down the associations tree.
73
- #
74
- # indexes :id, :as => :my_id
75
- # indexes :name, :sortable => true
76
- # indexes first_name, last_name, :sortable => true
77
- # indexes users.posts.content, :as => :post_content
78
- # indexes users(:id), :as => :user_ids
79
- #
80
- # Keep in mind that if any keywords for Ruby methods - such as id or
81
- # name - clash with your column names, you need to use the symbol
82
- # version (see the first, second and last examples above).
83
- #
84
- # If you specify multiple columns (example #2), a field will be created
85
- # for each. Don't use the :as option in this case. If you want to merge
86
- # those columns together, continue reading.
87
- #
88
- # Adding Multi-Column Fields:
89
- #
90
- # indexes [first_name, last_name], :as => :name
91
- # indexes [location, parent.location], :as => :location
92
- #
93
- # To combine multiple columns into a single field, you need to wrap
94
- # them in an Array, as shown by the above examples. There's no
95
- # limitations on whether they're symbols or methods or what level of
96
- # associations they come from.
97
- #
98
- # Adding SQL Fragment Fields
99
- #
100
- # You can also define a field using an SQL fragment, useful for when
101
- # you would like to index a calculated value.
102
- #
103
- # indexes "age < 18", :as => :minor
104
- #
105
- def indexes(*args)
106
- options = args.extract_options!
107
- args.each do |columns|
108
- field = Field.new(@source, FauxColumn.coerce(columns), options)
109
-
110
- add_sort_attribute field, options if field.sortable
111
- add_facet_attribute field, options if field.faceted
112
- end
113
- end
114
-
115
- # This is the method to add attributes to your index (hence why it is
116
- # aliased as 'attribute'). The syntax is the same as #indexes, so use
117
- # that as starting point, but keep in mind the following points.
118
- #
119
- # An attribute can have an alias (the :as option), but it is always
120
- # sortable - so you don't need to explicitly request that. You _can_
121
- # specify the data type of the attribute (the :type option), but the
122
- # code's pretty good at figuring that out itself from peering into the
123
- # database.
124
- #
125
- # Attributes are limited to the following types: integers, floats,
126
- # datetimes (converted to timestamps), booleans and strings. Don't
127
- # forget that Sphinx converts string attributes to integers, which are
128
- # useful for sorting, but that's about it.
129
- #
130
- # You can also have a collection of integers for multi-value attributes
131
- # (MVAs). Generally these would be through a has_many relationship,
132
- # like in this example:
133
- #
134
- # has posts(:id), :as => :post_ids
135
- #
136
- # This allows you to filter on any of the values tied to a specific
137
- # record. Might be best to read through the Sphinx documentation to get
138
- # a better idea of that though.
139
- #
140
- # Adding SQL Fragment Attributes
141
- #
142
- # You can also define an attribute using an SQL fragment, useful for
143
- # when you would like to index a calculated value. Don't forget to set
144
- # the type of the attribute though:
145
- #
146
- # has "age < 18", :as => :minor, :type => :boolean
147
- #
148
- # If you're creating attributes for latitude and longitude, don't
149
- # forget that Sphinx expects these values to be in radians.
150
- #
151
- def has(*args)
152
- options = args.extract_options!
153
- args.each do |columns|
154
- attribute = Attribute.new(@source, FauxColumn.coerce(columns), options)
155
-
156
- add_facet_attribute attribute, options if attribute.faceted
157
- end
158
- end
159
-
160
- def facet(*args)
161
- options = args.extract_options!
162
- options[:facet] = true
163
-
164
- args.each do |columns|
165
- attribute = Attribute.new(@source, FauxColumn.coerce(columns), options)
166
-
167
- add_facet_attribute attribute, options
168
- end
169
- end
170
-
171
- # Use this method to add some manual SQL conditions for your index
172
- # request. You can pass in as many strings as you like, they'll get
173
- # joined together with ANDs later on.
174
- #
175
- # where "user_id = 10"
176
- # where "parent_type = 'Article'", "created_at < NOW()"
177
- #
178
- def where(*args)
179
- @source.conditions += args
180
- end
181
-
182
- # Use this method to add some manual SQL strings to the GROUP BY
183
- # clause. You can pass in as many strings as you'd like, they'll get
184
- # joined together with commas later on.
185
- #
186
- # group_by "lat", "lng"
187
- #
188
- def group_by(*args)
189
- @source.groupings += args
190
- end
191
-
192
- # This is what to use to set properties on the index. Chief amongst
193
- # those is the delta property - to allow automatic updates to your
194
- # indexes as new models are added and edited - but also you can
195
- # define search-related properties which will be the defaults for all
196
- # searches on the model.
197
- #
198
- # set_property :delta => true
199
- # set_property :field_weights => {"name" => 100}
200
- # set_property :order => "name ASC"
201
- # set_property :select => 'name'
202
- #
203
- # Also, the following two properties are particularly relevant for
204
- # geo-location searching - latitude_attr and longitude_attr. If your
205
- # attributes for these two values are named something other than
206
- # lat/latitude or lon/long/longitude, you can dictate what they are
207
- # when defining the index, so you don't need to specify them for every
208
- # geo-related search.
209
- #
210
- # set_property :latitude_attr => "lt", :longitude_attr => "lg"
211
- #
212
- # Please don't forget to add a boolean field named 'delta' to your
213
- # model's database table if enabling the delta index for it.
214
- # Valid options for the delta property are:
215
- #
216
- # true
217
- # false
218
- # :default
219
- # :delayed
220
- # :datetime
221
- #
222
- # You can also extend ThinkingSphinx::Deltas::DefaultDelta to implement
223
- # your own handling for delta indexing.
224
- #
225
- def set_property(*args)
226
- options = args.extract_options!
227
- options.each do |key, value|
228
- set_single_property key, value
229
- end
230
-
231
- set_single_property args[0], args[1] if args.length == 2
232
- end
233
- alias_method :set_properties, :set_property
234
-
235
- # Handles the generation of new columns for the field and attribute
236
- # definitions.
237
- #
238
- def method_missing(method, *args)
239
- FauxColumn.new(method, *args)
240
- end
241
-
242
- # A method to allow adding fields from associations which have names
243
- # that clash with method names in the Builder class (ie: properties,
244
- # fields, attributes).
245
- #
246
- # Example: indexes assoc(:properties).column
247
- #
248
- def assoc(assoc, *args)
249
- FauxColumn.new(assoc, *args)
250
- end
251
-
252
- private
253
-
254
- def set_single_property(key, value)
255
- source_options = ThinkingSphinx::Configuration::SourceOptions
256
- if source_options.include?(key.to_s)
257
- @source.options.merge! key => value
258
- else
259
- @index.local_options.merge! key => value
260
- end
261
- end
262
-
263
- def add_sort_attribute(field, options)
264
- add_internal_attribute field, options, "_sort"
265
- end
266
-
267
- def add_facet_attribute(property, options)
268
- add_internal_attribute property, options, "_facet", true
269
- @index.model.sphinx_facets << property.to_facet
270
- end
271
-
272
- def add_internal_attribute(property, options, suffix, crc = false)
273
- return unless ThinkingSphinx::Facet.translate?(property)
274
-
275
- Attribute.new(@source,
276
- property.columns.collect { |col| col.clone },
277
- options.merge(
278
- :type => property.is_a?(Field) ? :string : options[:type],
279
- :as => property.unique_name.to_s.concat(suffix).to_sym,
280
- :crc => crc
281
- ).except(:facet)
282
- )
283
- end
284
- end
285
- end
286
- end
@@ -1,110 +0,0 @@
1
- module ThinkingSphinx
2
- class Index
3
- # Instances of this class represent database columns and the stack of
4
- # associations that lead from the base model to them.
5
- #
6
- # The name and stack are accessible through methods starting with __ to
7
- # avoid conflicting with the method_missing calls that build the stack.
8
- #
9
- class FauxColumn
10
- # Create a new column with a pre-defined stack. The top element in the
11
- # stack will get shifted to be the name value.
12
- #
13
- def initialize(*stack)
14
- @name = stack.pop
15
- @stack = stack
16
- end
17
-
18
- def self.coerce(columns)
19
- case columns
20
- when Symbol, String
21
- FauxColumn.new(columns)
22
- when Array
23
- columns.collect { |col| FauxColumn.coerce(col) }
24
- when FauxColumn
25
- columns
26
- else
27
- nil
28
- end
29
- end
30
-
31
- # Can't use normal method name, as that could be an association or
32
- # column name.
33
- #
34
- def __name
35
- @name
36
- end
37
-
38
- # Can't use normal method name, as that could be an association or
39
- # column name.
40
- #
41
- def __stack
42
- @stack
43
- end
44
-
45
- # Returns true if the stack is empty *and* if the name is a string -
46
- # which is an indication that of raw SQL, as opposed to a value from a
47
- # table's column.
48
- #
49
- def is_string?
50
- @name.is_a?(String) && @stack.empty?
51
- end
52
-
53
- # This handles any 'invalid' method calls and sets them as the name,
54
- # and pushing the previous name into the stack. The object returns
55
- # itself.
56
- #
57
- # If there's a single argument, it becomes the name, and the method
58
- # symbol goes into the stack as well. Multiple arguments means new
59
- # columns with the original stack and new names (from each argument) gets
60
- # returned.
61
- #
62
- # Easier to explain with examples:
63
- #
64
- # col = FauxColumn.new :a, :b, :c
65
- # col.__name #=> :c
66
- # col.__stack #=> [:a, :b]
67
- #
68
- # col.whatever #=> col
69
- # col.__name #=> :whatever
70
- # col.__stack #=> [:a, :b, :c]
71
- #
72
- # col.something(:id) #=> col
73
- # col.__name #=> :id
74
- # col.__stack #=> [:a, :b, :c, :whatever, :something]
75
- #
76
- # cols = col.short(:x, :y, :z)
77
- # cols[0].__name #=> :x
78
- # cols[0].__stack #=> [:a, :b, :c, :whatever, :something, :short]
79
- # cols[1].__name #=> :y
80
- # cols[1].__stack #=> [:a, :b, :c, :whatever, :something, :short]
81
- # cols[2].__name #=> :z
82
- # cols[2].__stack #=> [:a, :b, :c, :whatever, :something, :short]
83
- #
84
- # Also, this allows method chaining to build up a relevant stack:
85
- #
86
- # col = FauxColumn.new :a, :b
87
- # col.__name #=> :b
88
- # col.__stack #=> [:a]
89
- #
90
- # col.one.two.three #=> col
91
- # col.__name #=> :three
92
- # col.__stack #=> [:a, :b, :one, :two]
93
- #
94
- def method_missing(method, *args)
95
- @stack << @name
96
- @name = method
97
-
98
- if (args.empty?)
99
- self
100
- elsif (args.length == 1)
101
- method_missing(args.first)
102
- else
103
- args.collect { |arg|
104
- FauxColumn.new(@stack + [@name, arg])
105
- }
106
- end
107
- end
108
- end
109
- end
110
- end
@@ -1,162 +0,0 @@
1
- module ThinkingSphinx
2
- class Property
3
- attr_accessor :alias, :columns, :associations, :model, :faceted, :admin
4
-
5
- def initialize(source, columns, options = {})
6
- @source = source
7
- @model = source.model
8
- @columns = Array(columns)
9
- @associations = {}
10
-
11
- raise "Cannot define a field or attribute in #{source.model.name} with no columns. Maybe you are trying to index a field with a reserved name (id, name). You can fix this error by using a symbol rather than a bare name (:id instead of id)." if @columns.empty? || @columns.any? { |column| !column.respond_to?(:__stack) }
12
-
13
- @alias = options[:as]
14
- @faceted = options[:facet]
15
- @admin = options[:admin]
16
-
17
- @alias = @alias.to_sym unless @alias.blank?
18
-
19
- @columns.each { |col|
20
- @associations[col] = association_stack(col.__stack.clone).each { |assoc|
21
- assoc.join_to(source.base)
22
- }
23
- }
24
- end
25
-
26
- # Returns the unique name of the attribute - which is either the alias of
27
- # the attribute, or the name of the only column - if there is only one. If
28
- # there isn't, there should be an alias. Else things probably won't work.
29
- # Consider yourself warned.
30
- #
31
- def unique_name
32
- if @columns.length == 1
33
- @alias || @columns.first.__name
34
- else
35
- @alias
36
- end
37
- end
38
-
39
- def to_facet
40
- return nil unless @faceted
41
-
42
- ThinkingSphinx::Facet.new(self)
43
- end
44
-
45
- # Get the part of the GROUP BY clause related to this attribute - if one is
46
- # needed. If not, all you'll get back is nil. The latter will happen if
47
- # there isn't actually a real column to get data from, or if there's
48
- # multiple data values (read: a has_many or has_and_belongs_to_many
49
- # association).
50
- #
51
- def to_group_sql
52
- case
53
- when is_many?, is_string?, ThinkingSphinx.use_group_by_shortcut?
54
- nil
55
- else
56
- @columns.collect { |column|
57
- column_with_prefix(column)
58
- }
59
- end
60
- end
61
-
62
- def changed?(instance)
63
- return true if is_string? || @columns.any? { |col| !col.__stack.empty? }
64
-
65
- !@columns.all? { |col|
66
- instance.respond_to?("#{col.__name.to_s}_changed?") &&
67
- !instance.send("#{col.__name.to_s}_changed?")
68
- }
69
- end
70
-
71
- def admin?
72
- admin
73
- end
74
-
75
- def public?
76
- !admin
77
- end
78
-
79
- private
80
-
81
- # Could there be more than one value related to the parent record? If so,
82
- # then this will return true. If not, false. It's that simple.
83
- #
84
- def is_many?
85
- associations.values.flatten.any? { |assoc| assoc.is_many? }
86
- end
87
-
88
- # Returns true if any of the columns are string values, instead of database
89
- # column references.
90
- def is_string?
91
- columns.all? { |col| col.is_string? }
92
- end
93
-
94
- def adapter
95
- @adapter ||= @model.sphinx_database_adapter
96
- end
97
-
98
- def quote_with_table(table, column)
99
- "#{quote_table_name(table)}.#{quote_column(column)}"
100
- end
101
-
102
- def quote_column(column)
103
- @model.connection.quote_column_name(column)
104
- end
105
-
106
- def quote_table_name(table_name)
107
- @model.connection.quote_table_name(table_name)
108
- end
109
-
110
- # Indication of whether the columns should be concatenated with a space
111
- # between each value. True if there's either multiple sources or multiple
112
- # associations.
113
- #
114
- def concat_ws?
115
- multiple_associations? || @columns.length > 1
116
- end
117
-
118
- # Checks whether any column requires multiple associations (which only
119
- # happens for polymorphic situations).
120
- #
121
- def multiple_associations?
122
- associations.any? { |col,assocs| assocs.length > 1 }
123
- end
124
-
125
- # Builds a column reference tied to the appropriate associations. This
126
- # dives into the associations hash and their corresponding joins to
127
- # figure out how to correctly reference a column in SQL.
128
- #
129
- def column_with_prefix(column)
130
- if column.is_string?
131
- column.__name
132
- elsif associations[column].empty?
133
- "#{@model.quoted_table_name}.#{quote_column(column.__name)}"
134
- else
135
- associations[column].collect { |assoc|
136
- assoc.has_column?(column.__name) ?
137
- "#{quote_with_table(assoc.join.aliased_table_name, column.__name)}" :
138
- nil
139
- }.compact.join(', ')
140
- end
141
- end
142
-
143
- # Gets a stack of associations for a specific path.
144
- #
145
- def association_stack(path, parent = nil)
146
- assocs = []
147
-
148
- if parent.nil?
149
- assocs = @source.association(path.shift)
150
- else
151
- assocs = parent.children(path.shift)
152
- end
153
-
154
- until path.empty?
155
- point = path.shift
156
- assocs = assocs.collect { |assoc| assoc.children(point) }.flatten
157
- end
158
-
159
- assocs
160
- end
161
- end
162
- end