thinking-sphinx 2.1.0 → 3.0.0.pre

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 (352) hide show
  1. data/.gitignore +8 -0
  2. data/.travis.yml +13 -0
  3. data/Appraisals +7 -0
  4. data/Gemfile +10 -0
  5. data/HISTORY +2 -267
  6. data/LICENCE +1 -1
  7. data/README.textile +194 -226
  8. data/Rakefile +24 -0
  9. data/gemfiles/.gitignore +1 -0
  10. data/gemfiles/rails_3_1.gemfile +11 -0
  11. data/gemfiles/rails_3_2.gemfile +11 -0
  12. data/lib/thinking-sphinx.rb +1 -1
  13. data/lib/thinking_sphinx.rb +34 -292
  14. data/lib/thinking_sphinx/active_record.rb +22 -383
  15. data/lib/thinking_sphinx/active_record/association.rb +9 -0
  16. data/lib/thinking_sphinx/active_record/association_proxy.rb +68 -0
  17. data/lib/thinking_sphinx/active_record/associations.rb +68 -0
  18. data/lib/thinking_sphinx/active_record/attribute.rb +20 -0
  19. data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +32 -0
  20. data/lib/thinking_sphinx/active_record/attribute/type.rb +79 -0
  21. data/lib/thinking_sphinx/active_record/attribute/values.rb +18 -0
  22. data/lib/thinking_sphinx/active_record/base.rb +36 -0
  23. data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +31 -0
  24. data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +55 -0
  25. data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +59 -0
  26. data/lib/thinking_sphinx/active_record/column.rb +30 -0
  27. data/lib/thinking_sphinx/active_record/database_adapters.rb +51 -0
  28. data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +13 -0
  29. data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +23 -0
  30. data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +25 -0
  31. data/lib/thinking_sphinx/active_record/field.rb +11 -0
  32. data/lib/thinking_sphinx/active_record/index.rb +55 -0
  33. data/lib/thinking_sphinx/active_record/interpreter.rb +47 -0
  34. data/lib/thinking_sphinx/active_record/log_subscriber.rb +10 -58
  35. data/lib/thinking_sphinx/active_record/property.rb +28 -0
  36. data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +60 -0
  37. data/lib/thinking_sphinx/active_record/sql_builder.rb +159 -0
  38. data/lib/thinking_sphinx/active_record/sql_source.rb +138 -0
  39. data/lib/thinking_sphinx/active_record/sql_source/template.rb +46 -0
  40. data/lib/thinking_sphinx/batched_search.rb +26 -0
  41. data/lib/thinking_sphinx/callbacks.rb +15 -0
  42. data/lib/thinking_sphinx/configuration.rb +80 -331
  43. data/lib/thinking_sphinx/configuration/consistent_ids.rb +31 -0
  44. data/lib/thinking_sphinx/configuration/defaults.rb +5 -0
  45. data/lib/thinking_sphinx/core.rb +6 -0
  46. data/lib/thinking_sphinx/core/index.rb +68 -0
  47. data/lib/thinking_sphinx/core/interpreter.rb +19 -0
  48. data/lib/thinking_sphinx/deltas.rb +35 -26
  49. data/lib/thinking_sphinx/deltas/default_delta.rb +56 -56
  50. data/lib/thinking_sphinx/excerpter.rb +23 -21
  51. data/lib/thinking_sphinx/facet.rb +22 -127
  52. data/lib/thinking_sphinx/facet_search.rb +95 -162
  53. data/lib/thinking_sphinx/index.rb +39 -143
  54. data/lib/thinking_sphinx/index_set.rb +51 -0
  55. data/lib/thinking_sphinx/masks.rb +8 -0
  56. data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +23 -0
  57. data/lib/thinking_sphinx/masks/pagination_mask.rb +60 -0
  58. data/lib/thinking_sphinx/masks/scopes_mask.rb +35 -0
  59. data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +11 -0
  60. data/lib/thinking_sphinx/middlewares.rb +36 -0
  61. data/lib/thinking_sphinx/middlewares/active_record_translator.rb +73 -0
  62. data/lib/thinking_sphinx/middlewares/geographer.rb +53 -0
  63. data/lib/thinking_sphinx/middlewares/glazier.rb +39 -0
  64. data/lib/thinking_sphinx/middlewares/ids_only.rb +13 -0
  65. data/lib/thinking_sphinx/middlewares/inquirer.rb +62 -0
  66. data/lib/thinking_sphinx/middlewares/middleware.rb +9 -0
  67. data/lib/thinking_sphinx/middlewares/sphinxql.rb +149 -0
  68. data/lib/thinking_sphinx/middlewares/stale_id_checker.rb +45 -0
  69. data/lib/thinking_sphinx/middlewares/stale_id_filter.rb +46 -0
  70. data/lib/thinking_sphinx/panes.rb +8 -0
  71. data/lib/thinking_sphinx/panes/attributes_pane.rb +9 -0
  72. data/lib/thinking_sphinx/panes/distance_pane.rb +13 -0
  73. data/lib/thinking_sphinx/panes/excerpts_pane.rb +37 -0
  74. data/lib/thinking_sphinx/panes/weight_pane.rb +9 -0
  75. data/lib/thinking_sphinx/railtie.rb +6 -40
  76. data/lib/thinking_sphinx/rake_interface.rb +47 -0
  77. data/lib/thinking_sphinx/real_time.rb +11 -0
  78. data/lib/thinking_sphinx/real_time/attribute.rb +5 -0
  79. data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +48 -0
  80. data/lib/thinking_sphinx/real_time/field.rb +3 -0
  81. data/lib/thinking_sphinx/real_time/index.rb +47 -0
  82. data/lib/thinking_sphinx/real_time/index/template.rb +33 -0
  83. data/lib/thinking_sphinx/real_time/interpreter.rb +23 -0
  84. data/lib/thinking_sphinx/real_time/property.rb +16 -0
  85. data/lib/thinking_sphinx/scopes.rb +22 -0
  86. data/lib/thinking_sphinx/search.rb +90 -1028
  87. data/lib/thinking_sphinx/search/batch_inquirer.rb +27 -0
  88. data/lib/thinking_sphinx/search/context.rb +26 -0
  89. data/lib/thinking_sphinx/search/glaze.rb +32 -0
  90. data/lib/thinking_sphinx/search/merger.rb +24 -0
  91. data/lib/thinking_sphinx/search/query.rb +43 -0
  92. data/lib/thinking_sphinx/search/stale_ids_exception.rb +11 -0
  93. data/lib/thinking_sphinx/search/translator.rb +50 -0
  94. data/lib/thinking_sphinx/tasks.rb +22 -125
  95. data/lib/thinking_sphinx/test.rb +9 -19
  96. data/sketchpad.rb +58 -0
  97. data/spec/acceptance/association_scoping_spec.rb +23 -0
  98. data/spec/acceptance/attribute_access_spec.rb +39 -0
  99. data/spec/acceptance/attribute_updates_spec.rb +16 -0
  100. data/spec/acceptance/batch_searching_spec.rb +21 -0
  101. data/spec/acceptance/big_integers_spec.rb +27 -0
  102. data/spec/acceptance/excerpts_spec.rb +14 -0
  103. data/spec/acceptance/facets_spec.rb +122 -0
  104. data/spec/acceptance/geosearching_spec.rb +39 -0
  105. data/spec/acceptance/grouping_by_attributes_spec.rb +77 -0
  106. data/spec/acceptance/paginating_search_results_spec.rb +24 -0
  107. data/spec/acceptance/remove_deleted_records_spec.rb +23 -0
  108. data/spec/acceptance/search_counts_spec.rb +18 -0
  109. data/spec/acceptance/search_for_just_ids_spec.rb +19 -0
  110. data/spec/acceptance/searching_across_models_spec.rb +28 -0
  111. data/spec/acceptance/searching_on_fields_spec.rb +56 -0
  112. data/spec/acceptance/searching_with_filters_spec.rb +109 -0
  113. data/spec/acceptance/searching_with_sti_spec.rb +55 -0
  114. data/spec/acceptance/searching_within_a_model_spec.rb +52 -0
  115. data/spec/acceptance/sorting_search_results_spec.rb +41 -0
  116. data/spec/acceptance/spec_helper.rb +4 -0
  117. data/spec/acceptance/specifying_sql_spec.rb +62 -0
  118. data/spec/acceptance/sphinx_scopes_spec.rb +49 -0
  119. data/spec/acceptance/sql_deltas_spec.rb +43 -0
  120. data/spec/acceptance/support/database_cleaner.rb +11 -0
  121. data/spec/acceptance/support/sphinx_controller.rb +39 -0
  122. data/spec/acceptance/support/sphinx_helpers.rb +24 -0
  123. data/spec/acceptance/suspended_deltas_spec.rb +20 -0
  124. data/spec/internal/.gitignore +1 -0
  125. data/spec/internal/app/indices/animal_index.rb +3 -0
  126. data/spec/internal/app/indices/article_index.rb +24 -0
  127. data/spec/internal/app/indices/book_index.rb +8 -0
  128. data/spec/internal/app/indices/city_index.rb +6 -0
  129. data/spec/internal/app/indices/product_index.rb +3 -0
  130. data/spec/internal/app/indices/tee_index.rb +4 -0
  131. data/spec/internal/app/indices/user_index.rb +5 -0
  132. data/spec/internal/app/models/animal.rb +2 -0
  133. data/spec/internal/app/models/article.rb +5 -0
  134. data/spec/internal/app/models/bird.rb +2 -0
  135. data/spec/internal/app/models/book.rb +11 -0
  136. data/spec/internal/app/models/city.rb +2 -0
  137. data/spec/internal/app/models/colour.rb +3 -0
  138. data/spec/internal/app/models/flightless_bird.rb +2 -0
  139. data/spec/internal/app/models/mammal.rb +2 -0
  140. data/spec/internal/app/models/product.rb +3 -0
  141. data/spec/internal/app/models/tag.rb +4 -0
  142. data/{features/thinking_sphinx → spec/internal/app}/models/tagging.rb +1 -1
  143. data/spec/internal/app/models/tee.rb +3 -0
  144. data/spec/internal/app/models/tweet.rb +3 -0
  145. data/spec/internal/app/models/user.rb +3 -0
  146. data/spec/internal/config/database.yml +5 -0
  147. data/spec/internal/db/schema.rb +65 -0
  148. data/spec/internal/log/.gitignore +1 -0
  149. data/spec/spec_helper.rb +8 -49
  150. data/spec/support/sphinx_yaml_helpers.rb +9 -0
  151. data/spec/thinking_sphinx/active_record/association_spec.rb +12 -0
  152. data/spec/thinking_sphinx/active_record/associations_spec.rb +184 -0
  153. data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +147 -0
  154. data/spec/thinking_sphinx/active_record/base_spec.rb +61 -0
  155. data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +80 -0
  156. data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +147 -0
  157. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +69 -0
  158. data/spec/thinking_sphinx/active_record/column_spec.rb +47 -0
  159. data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +31 -0
  160. data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +43 -0
  161. data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +45 -0
  162. data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +108 -0
  163. data/spec/thinking_sphinx/active_record/field_spec.rb +36 -0
  164. data/spec/thinking_sphinx/active_record/index_spec.rb +208 -0
  165. data/spec/thinking_sphinx/active_record/interpreter_spec.rb +293 -0
  166. data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +162 -0
  167. data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +666 -0
  168. data/spec/thinking_sphinx/active_record/sql_source_spec.rb +401 -0
  169. data/spec/thinking_sphinx/configuration_spec.rb +264 -171
  170. data/spec/thinking_sphinx/deltas/default_delta_spec.rb +116 -0
  171. data/spec/thinking_sphinx/deltas_spec.rb +58 -0
  172. data/spec/thinking_sphinx/excerpter_spec.rb +40 -38
  173. data/spec/thinking_sphinx/facet_search_spec.rb +49 -151
  174. data/spec/thinking_sphinx/index_set_spec.rb +68 -0
  175. data/spec/thinking_sphinx/index_spec.rb +91 -155
  176. data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +121 -0
  177. data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +68 -0
  178. data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +132 -0
  179. data/spec/thinking_sphinx/middlewares/geographer_spec.rb +89 -0
  180. data/spec/thinking_sphinx/middlewares/glazier_spec.rb +62 -0
  181. data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +55 -0
  182. data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +271 -0
  183. data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +47 -0
  184. data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +91 -0
  185. data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +21 -0
  186. data/spec/thinking_sphinx/panes/distance_pane_spec.rb +41 -0
  187. data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +53 -0
  188. data/spec/thinking_sphinx/panes/weight_pane_spec.rb +20 -0
  189. data/spec/thinking_sphinx/rake_interface_spec.rb +147 -0
  190. data/spec/thinking_sphinx/real_time/attribute_spec.rb +62 -0
  191. data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +76 -0
  192. data/spec/thinking_sphinx/real_time/field_spec.rb +54 -0
  193. data/spec/thinking_sphinx/real_time/index_spec.rb +154 -0
  194. data/spec/thinking_sphinx/real_time/interpreter_spec.rb +147 -0
  195. data/spec/thinking_sphinx/scopes_spec.rb +38 -0
  196. data/spec/thinking_sphinx/search/glaze_spec.rb +55 -0
  197. data/spec/thinking_sphinx/search/query_spec.rb +46 -0
  198. data/spec/thinking_sphinx/search_spec.rb +65 -1357
  199. data/spec/thinking_sphinx_spec.rb +19 -182
  200. data/thinking-sphinx.gemspec +33 -0
  201. metadata +318 -431
  202. data/features/abstract_inheritance.feature +0 -10
  203. data/features/alternate_primary_key.feature +0 -27
  204. data/features/attribute_transformation.feature +0 -22
  205. data/features/attribute_updates.feature +0 -79
  206. data/features/deleting_instances.feature +0 -70
  207. data/features/direct_attributes.feature +0 -11
  208. data/features/excerpts.feature +0 -21
  209. data/features/extensible_delta_indexing.feature +0 -9
  210. data/features/facets.feature +0 -88
  211. data/features/facets_across_model.feature +0 -29
  212. data/features/field_sorting.feature +0 -18
  213. data/features/handling_edits.feature +0 -97
  214. data/features/retry_stale_indexes.feature +0 -24
  215. data/features/searching_across_models.feature +0 -20
  216. data/features/searching_by_index.feature +0 -41
  217. data/features/searching_by_model.feature +0 -175
  218. data/features/searching_with_find_arguments.feature +0 -56
  219. data/features/sphinx_detection.feature +0 -25
  220. data/features/sphinx_scopes.feature +0 -68
  221. data/features/step_definitions/alpha_steps.rb +0 -16
  222. data/features/step_definitions/beta_steps.rb +0 -7
  223. data/features/step_definitions/common_steps.rb +0 -205
  224. data/features/step_definitions/extensible_delta_indexing_steps.rb +0 -7
  225. data/features/step_definitions/facet_steps.rb +0 -96
  226. data/features/step_definitions/find_arguments_steps.rb +0 -36
  227. data/features/step_definitions/gamma_steps.rb +0 -15
  228. data/features/step_definitions/scope_steps.rb +0 -19
  229. data/features/step_definitions/search_steps.rb +0 -94
  230. data/features/step_definitions/sphinx_steps.rb +0 -35
  231. data/features/sti_searching.feature +0 -19
  232. data/features/support/env.rb +0 -24
  233. data/features/support/lib/generic_delta_handler.rb +0 -8
  234. data/features/thinking_sphinx/database.example.yml +0 -3
  235. data/features/thinking_sphinx/db/.gitignore +0 -1
  236. data/features/thinking_sphinx/db/fixtures/alphas.rb +0 -8
  237. data/features/thinking_sphinx/db/fixtures/authors.rb +0 -1
  238. data/features/thinking_sphinx/db/fixtures/betas.rb +0 -11
  239. data/features/thinking_sphinx/db/fixtures/boxes.rb +0 -9
  240. data/features/thinking_sphinx/db/fixtures/categories.rb +0 -1
  241. data/features/thinking_sphinx/db/fixtures/cats.rb +0 -3
  242. data/features/thinking_sphinx/db/fixtures/comments.rb +0 -24
  243. data/features/thinking_sphinx/db/fixtures/developers.rb +0 -31
  244. data/features/thinking_sphinx/db/fixtures/dogs.rb +0 -3
  245. data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +0 -10
  246. data/features/thinking_sphinx/db/fixtures/foxes.rb +0 -3
  247. data/features/thinking_sphinx/db/fixtures/gammas.rb +0 -10
  248. data/features/thinking_sphinx/db/fixtures/music.rb +0 -4
  249. data/features/thinking_sphinx/db/fixtures/people.rb +0 -1001
  250. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +0 -1
  251. data/features/thinking_sphinx/db/fixtures/posts.rb +0 -10
  252. data/features/thinking_sphinx/db/fixtures/robots.rb +0 -8
  253. data/features/thinking_sphinx/db/fixtures/tags.rb +0 -27
  254. data/features/thinking_sphinx/db/migrations/create_alphas.rb +0 -8
  255. data/features/thinking_sphinx/db/migrations/create_animals.rb +0 -5
  256. data/features/thinking_sphinx/db/migrations/create_authors.rb +0 -3
  257. data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +0 -6
  258. data/features/thinking_sphinx/db/migrations/create_betas.rb +0 -5
  259. data/features/thinking_sphinx/db/migrations/create_boxes.rb +0 -5
  260. data/features/thinking_sphinx/db/migrations/create_categories.rb +0 -3
  261. data/features/thinking_sphinx/db/migrations/create_comments.rb +0 -10
  262. data/features/thinking_sphinx/db/migrations/create_developers.rb +0 -7
  263. data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +0 -5
  264. data/features/thinking_sphinx/db/migrations/create_gammas.rb +0 -3
  265. data/features/thinking_sphinx/db/migrations/create_genres.rb +0 -3
  266. data/features/thinking_sphinx/db/migrations/create_music.rb +0 -6
  267. data/features/thinking_sphinx/db/migrations/create_people.rb +0 -13
  268. data/features/thinking_sphinx/db/migrations/create_posts.rb +0 -6
  269. data/features/thinking_sphinx/db/migrations/create_robots.rb +0 -4
  270. data/features/thinking_sphinx/db/migrations/create_taggings.rb +0 -5
  271. data/features/thinking_sphinx/db/migrations/create_tags.rb +0 -4
  272. data/features/thinking_sphinx/models/alpha.rb +0 -23
  273. data/features/thinking_sphinx/models/andrew.rb +0 -17
  274. data/features/thinking_sphinx/models/animal.rb +0 -5
  275. data/features/thinking_sphinx/models/author.rb +0 -3
  276. data/features/thinking_sphinx/models/beta.rb +0 -13
  277. data/features/thinking_sphinx/models/box.rb +0 -8
  278. data/features/thinking_sphinx/models/cat.rb +0 -3
  279. data/features/thinking_sphinx/models/category.rb +0 -4
  280. data/features/thinking_sphinx/models/comment.rb +0 -10
  281. data/features/thinking_sphinx/models/developer.rb +0 -21
  282. data/features/thinking_sphinx/models/dog.rb +0 -3
  283. data/features/thinking_sphinx/models/extensible_beta.rb +0 -9
  284. data/features/thinking_sphinx/models/fox.rb +0 -5
  285. data/features/thinking_sphinx/models/gamma.rb +0 -5
  286. data/features/thinking_sphinx/models/genre.rb +0 -3
  287. data/features/thinking_sphinx/models/medium.rb +0 -5
  288. data/features/thinking_sphinx/models/music.rb +0 -10
  289. data/features/thinking_sphinx/models/person.rb +0 -24
  290. data/features/thinking_sphinx/models/post.rb +0 -22
  291. data/features/thinking_sphinx/models/robot.rb +0 -12
  292. data/features/thinking_sphinx/models/tag.rb +0 -3
  293. data/lib/cucumber/thinking_sphinx/external_world.rb +0 -12
  294. data/lib/cucumber/thinking_sphinx/internal_world.rb +0 -137
  295. data/lib/cucumber/thinking_sphinx/sql_logger.rb +0 -28
  296. data/lib/thinking_sphinx/action_controller.rb +0 -31
  297. data/lib/thinking_sphinx/active_record/attribute_updates.rb +0 -54
  298. data/lib/thinking_sphinx/active_record/collection_proxy.rb +0 -47
  299. data/lib/thinking_sphinx/active_record/collection_proxy_with_scopes.rb +0 -27
  300. data/lib/thinking_sphinx/active_record/delta.rb +0 -67
  301. data/lib/thinking_sphinx/active_record/has_many_association.rb +0 -44
  302. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +0 -21
  303. data/lib/thinking_sphinx/active_record/scopes.rb +0 -110
  304. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +0 -94
  305. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -62
  306. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +0 -188
  307. data/lib/thinking_sphinx/association.rb +0 -230
  308. data/lib/thinking_sphinx/attribute.rb +0 -405
  309. data/lib/thinking_sphinx/auto_version.rb +0 -40
  310. data/lib/thinking_sphinx/bundled_search.rb +0 -40
  311. data/lib/thinking_sphinx/class_facet.rb +0 -20
  312. data/lib/thinking_sphinx/connection.rb +0 -71
  313. data/lib/thinking_sphinx/context.rb +0 -81
  314. data/lib/thinking_sphinx/core/string.rb +0 -15
  315. data/lib/thinking_sphinx/deltas/delete_job.rb +0 -16
  316. data/lib/thinking_sphinx/deltas/index_job.rb +0 -17
  317. data/lib/thinking_sphinx/deploy/capistrano.rb +0 -99
  318. data/lib/thinking_sphinx/field.rb +0 -98
  319. data/lib/thinking_sphinx/index/builder.rb +0 -315
  320. data/lib/thinking_sphinx/index/faux_column.rb +0 -118
  321. data/lib/thinking_sphinx/join.rb +0 -37
  322. data/lib/thinking_sphinx/property.rb +0 -187
  323. data/lib/thinking_sphinx/search_methods.rb +0 -439
  324. data/lib/thinking_sphinx/sinatra.rb +0 -7
  325. data/lib/thinking_sphinx/source.rb +0 -194
  326. data/lib/thinking_sphinx/source/internal_properties.rb +0 -51
  327. data/lib/thinking_sphinx/source/sql.rb +0 -174
  328. data/spec/fixtures/data.sql +0 -32
  329. data/spec/fixtures/database.yml.default +0 -3
  330. data/spec/fixtures/models.rb +0 -164
  331. data/spec/fixtures/structure.sql +0 -146
  332. data/spec/sphinx_helper.rb +0 -60
  333. data/spec/support/rails.rb +0 -25
  334. data/spec/thinking_sphinx/active_record/delta_spec.rb +0 -123
  335. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +0 -173
  336. data/spec/thinking_sphinx/active_record/scopes_spec.rb +0 -177
  337. data/spec/thinking_sphinx/active_record_spec.rb +0 -573
  338. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +0 -163
  339. data/spec/thinking_sphinx/association_spec.rb +0 -250
  340. data/spec/thinking_sphinx/attribute_spec.rb +0 -552
  341. data/spec/thinking_sphinx/auto_version_spec.rb +0 -103
  342. data/spec/thinking_sphinx/connection_spec.rb +0 -77
  343. data/spec/thinking_sphinx/context_spec.rb +0 -127
  344. data/spec/thinking_sphinx/core/array_spec.rb +0 -9
  345. data/spec/thinking_sphinx/core/string_spec.rb +0 -9
  346. data/spec/thinking_sphinx/facet_spec.rb +0 -359
  347. data/spec/thinking_sphinx/field_spec.rb +0 -127
  348. data/spec/thinking_sphinx/index/builder_spec.rb +0 -532
  349. data/spec/thinking_sphinx/index/faux_column_spec.rb +0 -36
  350. data/spec/thinking_sphinx/search_methods_spec.rb +0 -156
  351. data/spec/thinking_sphinx/source_spec.rb +0 -267
  352. data/spec/thinking_sphinx/test_spec.rb +0 -20
@@ -0,0 +1,9 @@
1
+ class ThinkingSphinx::ActiveRecord::Association
2
+ def initialize(column)
3
+ @column = column
4
+ end
5
+
6
+ def stack
7
+ @column.__stack + [@column.__name]
8
+ end
9
+ end
@@ -0,0 +1,68 @@
1
+ module ThinkingSphinx::ActiveRecord::AssociationProxy
2
+ extend ActiveSupport::Concern
3
+
4
+ def search(query = nil, options = {})
5
+ ThinkingSphinx::Search::Merger.new(super).merge! nil,
6
+ :with => association_filter
7
+ end
8
+
9
+ def search_for_ids(query = nil, options = {})
10
+ ThinkingSphinx::Search::Merger.new(super).merge! nil,
11
+ :with => association_filter
12
+ end
13
+
14
+ private
15
+
16
+ def association_filter
17
+ attribute = AttributeFinder.new(proxy_association).attribute
18
+
19
+ {attribute.name.to_sym => proxy_association.owner.id}
20
+ end
21
+
22
+ class AttributeFinder
23
+ def initialize(association)
24
+ @association = association
25
+ end
26
+
27
+ def attribute
28
+ attributes.detect { |attribute|
29
+ # Don't bother with attributes built from multiple columns
30
+ next unless attribute.columns.length == 1
31
+
32
+ attribute.columns.first.__name == foreign_key.to_sym ||
33
+ attribute.name == foreign_key.to_s
34
+ } or raise "Missing Attribute for Foreign Key #{foreign_key}"
35
+ end
36
+
37
+ private
38
+
39
+ def attributes
40
+ sources.collect(&:attributes).flatten
41
+ end
42
+
43
+ def configuration
44
+ ThinkingSphinx::Configuration.instance
45
+ end
46
+
47
+ def foreign_key
48
+ @foreign_key ||= if @association.reflection.through_reflection
49
+ @association.reflection.through_reflection.foreign_key
50
+ else
51
+ @association.reflection.foreign_key
52
+ end
53
+ end
54
+
55
+ def indices
56
+ @indices ||= begin
57
+ configuration.preload_indices
58
+ configuration.indices_for_references(
59
+ *@association.klass.name.underscore.to_sym
60
+ )
61
+ end
62
+ end
63
+
64
+ def sources
65
+ indices.collect(&:sources).flatten
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,68 @@
1
+ class ThinkingSphinx::ActiveRecord::Associations
2
+ JoinDependency = ::ActiveRecord::Associations::JoinDependency
3
+
4
+ attr_reader :model
5
+
6
+ def initialize(model)
7
+ @model = model
8
+ @joins = ActiveSupport::OrderedHash.new
9
+ end
10
+
11
+ def add_join_to(stack)
12
+ join_for(stack)
13
+ end
14
+
15
+ def aggregate_for?(stack)
16
+ return false if stack.empty?
17
+
18
+ joins_for(stack).any? { |join|
19
+ [:has_many, :has_and_belongs_to_many].include?(
20
+ join.reflection.macro
21
+ )
22
+ }
23
+ end
24
+
25
+ def alias_for(stack)
26
+ return model.quoted_table_name if stack.empty?
27
+
28
+ join_for(stack).aliased_table_name
29
+ end
30
+
31
+ def join_values
32
+ @joins.values
33
+ end
34
+
35
+ private
36
+
37
+ def base
38
+ @base ||= JoinDependency.new model, [], []
39
+ end
40
+
41
+ def join_for(stack)
42
+ @joins[stack] ||= begin
43
+ JoinDependency::JoinAssociation.new(
44
+ reflection_for(stack), base, parent_join_for(stack)
45
+ ).tap { |join| join.join_type = Arel::OuterJoin }
46
+ end
47
+ end
48
+
49
+ def joins_for(stack)
50
+ if stack.length == 1
51
+ [join_for(stack)]
52
+ else
53
+ [joins_for(stack[0..-2]), join_for(stack)].flatten
54
+ end
55
+ end
56
+
57
+ def parent_for(stack)
58
+ stack.length == 1 ? base : join_for(stack[0..-2])
59
+ end
60
+
61
+ def parent_join_for(stack)
62
+ stack.length == 1 ? base.join_base : parent_for(stack)
63
+ end
64
+
65
+ def reflection_for(stack)
66
+ parent_for(stack).active_record.reflections[stack.last]
67
+ end
68
+ end
@@ -0,0 +1,20 @@
1
+ class ThinkingSphinx::ActiveRecord::Attribute <
2
+ ThinkingSphinx::ActiveRecord::Property
3
+
4
+ delegate :type, :type=, :multi?, :updateable?, :to => :typist
5
+ delegate :value_for, :to => :values
6
+
7
+ private
8
+
9
+ def typist
10
+ @typist ||= ThinkingSphinx::ActiveRecord::Attribute::Type.new self, @model
11
+ end
12
+
13
+ def values
14
+ @values ||= ThinkingSphinx::ActiveRecord::Attribute::Values.new self
15
+ end
16
+ end
17
+
18
+ require 'thinking_sphinx/active_record/attribute/sphinx_presenter'
19
+ require 'thinking_sphinx/active_record/attribute/type'
20
+ require 'thinking_sphinx/active_record/attribute/values'
@@ -0,0 +1,32 @@
1
+ class ThinkingSphinx::ActiveRecord::Attribute::SphinxPresenter
2
+ SPHINX_TYPES = {
3
+ :integer => :uint,
4
+ :boolean => :bool,
5
+ :timestamp => :timestamp,
6
+ :float => :float,
7
+ :string => :string,
8
+ :bigint => :bigint,
9
+ :ordinal => :str2ordinal,
10
+ :wordcount => :str2wordcount
11
+ }
12
+
13
+ def initialize(attribute)
14
+ @attribute = attribute
15
+ end
16
+
17
+ def collection_type
18
+ @attribute.multi? ? :multi : sphinx_type
19
+ end
20
+
21
+ def declaration
22
+ if @attribute.multi?
23
+ "#{sphinx_type} #{@attribute.name} from field"
24
+ else
25
+ @attribute.name
26
+ end
27
+ end
28
+
29
+ def sphinx_type
30
+ SPHINX_TYPES[@attribute.type]
31
+ end
32
+ end
@@ -0,0 +1,79 @@
1
+ class ThinkingSphinx::ActiveRecord::Attribute::Type
2
+ UPDATEABLE_TYPES = [:integer, :timestamp, :boolean, :float]
3
+
4
+ def initialize(attribute, model)
5
+ @attribute, @model = attribute, model
6
+ end
7
+
8
+ def multi?
9
+ @multi ||= attribute.options[:multi] || multi_from_associations
10
+ end
11
+
12
+ def timestamp?
13
+ type == :timestamp
14
+ end
15
+
16
+ def type
17
+ @type ||= attribute.options[:type] || type_from_database
18
+ end
19
+
20
+ def type=(value)
21
+ @type = attribute.options[:type] = value
22
+ end
23
+
24
+ def updateable?
25
+ UPDATEABLE_TYPES.include?(type) && single_column_reference?
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :attribute, :model
31
+
32
+ def associations
33
+ @associations ||= begin
34
+ klass = model
35
+ attribute.columns.first.__stack.collect { |name|
36
+ association = klass.reflect_on_association(name)
37
+ klass = association.klass
38
+ association
39
+ }
40
+ end
41
+ end
42
+
43
+ def klass
44
+ @klass ||= associations.any? ? associations.last.klass : model
45
+ end
46
+
47
+ def multi_from_associations
48
+ associations.any? { |association|
49
+ [:has_many, :has_and_belongs_to_many].include?(association.macro)
50
+ }
51
+ end
52
+
53
+ def single_column_reference?
54
+ attribute.columns.length == 1 &&
55
+ attribute.columns.first.__stack.length == 0 &&
56
+ !attribute.columns.first.string?
57
+ end
58
+
59
+ def type_from_database
60
+ db_column = klass.columns.detect { |db_column|
61
+ db_column.name == attribute.columns.first.__name.to_s
62
+ }
63
+
64
+ if db_column.type == :integer && db_column.sql_type[/bigint/i]
65
+ return :bigint
66
+ end
67
+
68
+ case db_column.type
69
+ when :datetime, :date
70
+ :timestamp
71
+ when :text
72
+ :string
73
+ when :decimal
74
+ :float
75
+ else
76
+ db_column.type
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,18 @@
1
+ class ThinkingSphinx::ActiveRecord::Attribute::Values
2
+ def initialize(attribute)
3
+ @attribute = attribute
4
+ end
5
+
6
+ def value_for(instance)
7
+ object = column.__stack.inject(instance) { |object, name|
8
+ object.nil? ? nil : object.send(name)
9
+ }
10
+ object.nil? ? nil : object.send(column.__name)
11
+ end
12
+
13
+ private
14
+
15
+ def column
16
+ @attribute.columns.first
17
+ end
18
+ end
@@ -0,0 +1,36 @@
1
+ module ThinkingSphinx::ActiveRecord::Base
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ after_destroy ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks
6
+ before_save ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks
7
+ after_update ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks
8
+ after_commit ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks
9
+
10
+ after_save ThinkingSphinx::RealTime::Callbacks::RealTimeCallbacks
11
+
12
+ ::ActiveRecord::Associations::CollectionProxy.send :include,
13
+ ThinkingSphinx::ActiveRecord::AssociationProxy
14
+ end
15
+
16
+ module ClassMethods
17
+ def facets(query = nil, options = {})
18
+ search = ThinkingSphinx.facets query, options
19
+ ThinkingSphinx::Search::Merger.new(search).merge! nil, :classes => [self]
20
+ end
21
+
22
+ def search(query = nil, options = {})
23
+ search = ThinkingSphinx.search query, options
24
+ ThinkingSphinx::Search::Merger.new(search).merge! nil, :classes => [self]
25
+ end
26
+
27
+ def search_count(query = nil, options = {})
28
+ search(query, options).total_entries
29
+ end
30
+
31
+ def search_for_ids(query = nil, options = {})
32
+ search = search query, options
33
+ ThinkingSphinx::Search::Merger.new(search).merge! nil, :ids_only => true
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ class ThinkingSphinx::ActiveRecord::Callbacks::DeleteCallbacks <
2
+ ThinkingSphinx::Callbacks
3
+
4
+ callbacks :after_destroy
5
+
6
+ def after_destroy
7
+ indices.each do |index|
8
+ connection.query Riddle::Query.update(
9
+ index.name, index.document_id_for_key(instance.id),
10
+ :sphinx_deleted => true
11
+ )
12
+ end
13
+ rescue Mysql2::Error => error
14
+ # This isn't vital, so don't raise the error.
15
+ end
16
+
17
+ private
18
+
19
+ def config
20
+ ThinkingSphinx::Configuration.instance
21
+ end
22
+
23
+ def connection
24
+ @connection ||= config.connection
25
+ end
26
+
27
+ def indices
28
+ config.preload_indices
29
+ config.indices_for_references instance.class.name.underscore.to_sym
30
+ end
31
+ end
@@ -0,0 +1,55 @@
1
+ class ThinkingSphinx::ActiveRecord::Callbacks::DeltaCallbacks <
2
+ ThinkingSphinx::Callbacks
3
+
4
+ callbacks :after_commit, :before_save
5
+
6
+ def after_commit
7
+ return unless delta_indices? && processors.any? { |processor|
8
+ processor.toggled?(instance)
9
+ } && !ThinkingSphinx::Deltas.suspended?
10
+
11
+ delta_indices.each do |index|
12
+ index.delta_processor.index index
13
+ end
14
+
15
+ core_indices.each do |index|
16
+ index.delta_processor.delete index, instance
17
+ end
18
+ end
19
+
20
+ def before_save
21
+ return unless delta_indices?
22
+
23
+ processors.each { |processor| processor.toggle instance }
24
+ end
25
+
26
+ private
27
+
28
+ def config
29
+ ThinkingSphinx::Configuration.instance
30
+ end
31
+
32
+ def core_indices
33
+ @core_indices ||= indices.reject { |index| index.delta? }
34
+ end
35
+
36
+ def delta_indices
37
+ @delta_indices ||= indices.select { |index| index.delta? }
38
+ end
39
+
40
+ def delta_indices?
41
+ delta_indices.any?
42
+ end
43
+
44
+ def indices
45
+ @indices ||= config.indices_for_references reference
46
+ end
47
+
48
+ def processors
49
+ delta_indices.collect &:delta_processor
50
+ end
51
+
52
+ def reference
53
+ instance.class.name.underscore.to_sym
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ class ThinkingSphinx::ActiveRecord::Callbacks::UpdateCallbacks <
2
+ ThinkingSphinx::Callbacks
3
+
4
+ callbacks :after_update
5
+
6
+ def after_update
7
+ return unless updates_enabled?
8
+
9
+ indices.each do |index|
10
+ update index
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def attributes_hash_for(index)
17
+ updateable_attributes_for(index).inject({}) do |hash, attribute|
18
+ if instance.changed.include?(attribute.columns.first.__name.to_s)
19
+ hash[attribute.name] = attribute.value_for(instance)
20
+ end
21
+
22
+ hash
23
+ end
24
+ end
25
+
26
+ def configuration
27
+ ThinkingSphinx::Configuration.instance
28
+ end
29
+
30
+ def indices
31
+ @indices ||= configuration.indices_for_references reference
32
+ end
33
+
34
+ def reference
35
+ instance.class.name.underscore.to_sym
36
+ end
37
+
38
+ def update(index)
39
+ attributes = attributes_hash_for(index)
40
+ return if attributes.empty?
41
+
42
+ sphinxql = Riddle::Query.update(
43
+ index.name, index.document_id_for_key(instance.id), attributes
44
+ )
45
+ configuration.connection.query(sphinxql)
46
+ rescue Mysql2::Error => error
47
+ # This isn't vital, so don't raise the error.
48
+ end
49
+
50
+ def updateable_attributes_for(index)
51
+ index.sources.collect(&:attributes).flatten.select { |attribute|
52
+ attribute.updateable?
53
+ }
54
+ end
55
+
56
+ def updates_enabled?
57
+ configuration.settings['attribute_updates']
58
+ end
59
+ end