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
@@ -1,315 +0,0 @@
1
- require 'blankslate' unless defined?(::BasicObject)
2
-
3
- module ThinkingSphinx
4
- class Index
5
- # The Builder class is the core for the index definition block processing.
6
- # There are four methods you really need to pay attention to:
7
- # - indexes
8
- # - has
9
- # - where
10
- # - set_property/set_properties
11
- #
12
- # The first two of these methods allow you to define what data makes up
13
- # your indexes. #where provides a method to add manual SQL conditions, and
14
- # set_property allows you to set some settings on a per-index basis. Check
15
- # out each method's documentation for better ideas of usage.
16
- #
17
- class Builder < (defined?(::BasicObject) ? ::BasicObject : BlankSlate)
18
- def self.generate(model, name = nil, &block)
19
- index = ::ThinkingSphinx::Index.new(model)
20
- index.name = name unless name.nil?
21
-
22
- new(index, &block) if block_given?
23
-
24
- index.delta_object = ::ThinkingSphinx::Deltas.parse index
25
- index
26
- end
27
-
28
- def initialize(index, &block)
29
- @index = index
30
- @explicit_source = false
31
-
32
- self.instance_eval &block
33
-
34
- if no_fields?
35
- raise "At least one field is necessary for an index"
36
- end
37
- end
38
-
39
- def define_source(&block)
40
- if @explicit_source
41
- @source = ::ThinkingSphinx::Source.new(@index)
42
- @index.sources << @source
43
- else
44
- @explicit_source = true
45
- end
46
-
47
- self.instance_eval &block
48
- end
49
-
50
- def use_local_indices(*indexes)
51
- @index.additional_indices += indexes.map {|index_name| "#{index_name.to_s}_core"}
52
- end
53
- alias_method :use_local_index, :use_local_indices
54
-
55
- # This is how you add fields - the strings Sphinx looks at - to your
56
- # index. Technically, to use this method, you need to pass in some
57
- # columns and options - but there's some neat method_missing stuff
58
- # happening, so lets stick to the expected syntax within a define_index
59
- # block.
60
- #
61
- # Expected options are :as, which points to a column alias in symbol
62
- # form, and :sortable, which indicates whether you want to sort by this
63
- # field.
64
- #
65
- # Adding Single-Column Fields:
66
- #
67
- # You can use symbols or methods - and can chain methods together to
68
- # get access down the associations tree.
69
- #
70
- # indexes :id, :as => :my_id
71
- # indexes :name, :sortable => true
72
- # indexes first_name, last_name, :sortable => true
73
- # indexes users.posts.content, :as => :post_content
74
- # indexes users(:id), :as => :user_ids
75
- #
76
- # Keep in mind that if any keywords for Ruby methods - such as id or
77
- # name - clash with your column names, you need to use the symbol
78
- # version (see the first, second and last examples above).
79
- #
80
- # If you specify multiple columns (example #2), a field will be created
81
- # for each. Don't use the :as option in this case. If you want to merge
82
- # those columns together, continue reading.
83
- #
84
- # Adding Multi-Column Fields:
85
- #
86
- # indexes [first_name, last_name], :as => :name
87
- # indexes [location, parent.location], :as => :location
88
- #
89
- # To combine multiple columns into a single field, you need to wrap
90
- # them in an Array, as shown by the above examples. There's no
91
- # limitations on whether they're symbols or methods or what level of
92
- # associations they come from.
93
- #
94
- # Adding SQL Fragment Fields
95
- #
96
- # You can also define a field using an SQL fragment, useful for when
97
- # you would like to index a calculated value.
98
- #
99
- # indexes "age < 18", :as => :minor
100
- #
101
- def indexes(*args)
102
- options = args.extract_options!
103
- args.each do |columns|
104
- field = ::ThinkingSphinx::Field.new(source,
105
- ::ThinkingSphinx::Index::FauxColumn.coerce(columns), options)
106
-
107
- add_sort_attribute field, options if field.sortable
108
- add_facet_attribute field, options if field.faceted
109
- end
110
- end
111
-
112
- # This is the method to add attributes to your index (hence why it is
113
- # aliased as 'attribute'). The syntax is the same as #indexes, so use
114
- # that as starting point, but keep in mind the following points.
115
- #
116
- # An attribute can have an alias (the :as option), but it is always
117
- # sortable - so you don't need to explicitly request that. You _can_
118
- # specify the data type of the attribute (the :type option), but the
119
- # code's pretty good at figuring that out itself from peering into the
120
- # database.
121
- #
122
- # Attributes are limited to the following types: integers, floats,
123
- # datetimes (converted to timestamps), booleans, strings and MVAs
124
- # (:multi). Don't forget that Sphinx converts string attributes to
125
- # integers, which are useful for sorting, but that's about it.
126
- #
127
- # Collection of integers are known as multi-value attributes (MVAs).
128
- # Generally these would be through a has_many relationship, like in this
129
- # example:
130
- #
131
- # has posts(:id), :as => :post_ids
132
- #
133
- # This allows you to filter on any of the values tied to a specific
134
- # record. Might be best to read through the Sphinx documentation to get
135
- # a better idea of that though.
136
- #
137
- # Adding SQL Fragment Attributes
138
- #
139
- # You can also define an attribute using an SQL fragment, useful for
140
- # when you would like to index a calculated value. Don't forget to set
141
- # the type of the attribute though:
142
- #
143
- # has "age < 18", :as => :minor, :type => :boolean
144
- #
145
- # If you're creating attributes for latitude and longitude, don't
146
- # forget that Sphinx expects these values to be in radians.
147
- #
148
- def has(*args)
149
- options = args.extract_options!
150
- args.each do |columns|
151
- attribute = ::ThinkingSphinx::Attribute.new(source,
152
- ::ThinkingSphinx::Index::FauxColumn.coerce(columns), options)
153
-
154
- add_facet_attribute attribute, options if attribute.faceted
155
- end
156
- end
157
-
158
- def facet(*args)
159
- options = args.extract_options!
160
- options[:facet] = true
161
-
162
- args.each do |columns|
163
- attribute = ::ThinkingSphinx::Attribute.new(source,
164
- ::ThinkingSphinx::Index::FauxColumn.coerce(columns), options)
165
-
166
- add_facet_attribute attribute, options
167
- end
168
- end
169
-
170
- def join(*args)
171
- args.each do |association|
172
- ::ThinkingSphinx::Join.new(source, association)
173
- end
174
- end
175
-
176
- # Use this method to add some manual SQL conditions for your index
177
- # request. You can pass in as many strings as you like, they'll get
178
- # joined together with ANDs later on.
179
- #
180
- # where "user_id = 10"
181
- # where "parent_type = 'Article'", "created_at < NOW()"
182
- #
183
- def where(*args)
184
- source.conditions += args
185
- end
186
-
187
- # Use this method to add some manual SQL strings to the GROUP BY
188
- # clause. You can pass in as many strings as you'd like, they'll get
189
- # joined together with commas later on.
190
- #
191
- # group_by "lat", "lng"
192
- #
193
- def group_by(*args)
194
- source.groupings += args
195
- end
196
-
197
- # This is what to use to set properties on the index. Chief amongst
198
- # those is the delta property - to allow automatic updates to your
199
- # indexes as new models are added and edited - but also you can
200
- # define search-related properties which will be the defaults for all
201
- # searches on the model.
202
- #
203
- # set_property :delta => true
204
- # set_property :field_weights => {"name" => 100}
205
- # set_property :order => "name ASC"
206
- # set_property :select => 'name'
207
- #
208
- # Also, the following two properties are particularly relevant for
209
- # geo-location searching - latitude_attr and longitude_attr. If your
210
- # attributes for these two values are named something other than
211
- # lat/latitude or lon/long/longitude, you can dictate what they are
212
- # when defining the index, so you don't need to specify them for every
213
- # geo-related search.
214
- #
215
- # set_property :latitude_attr => "lt", :longitude_attr => "lg"
216
- #
217
- # Please don't forget to add a boolean field named 'delta' to your
218
- # model's database table if enabling the delta index for it.
219
- # Valid options for the delta property are:
220
- #
221
- # true
222
- # false
223
- # :default
224
- # :delayed
225
- # :datetime
226
- #
227
- # You can also extend ThinkingSphinx::Deltas::DefaultDelta to implement
228
- # your own handling for delta indexing.
229
- #
230
- def set_property(*args)
231
- options = args.extract_options!
232
- options.each do |key, value|
233
- set_single_property key, value
234
- end
235
-
236
- set_single_property args[0], args[1] if args.length == 2
237
- end
238
- alias_method :set_properties, :set_property
239
-
240
- # Handles the generation of new columns for the field and attribute
241
- # definitions.
242
- #
243
- def method_missing(method, *args)
244
- ::ThinkingSphinx::Index::FauxColumn.new(method, *args)
245
- end
246
-
247
- # A method to allow adding fields from associations which have names
248
- # that clash with method names in the Builder class (ie: properties,
249
- # fields, attributes).
250
- #
251
- # Example: indexes assoc(:properties).column
252
- #
253
- def assoc(assoc, *args)
254
- ::ThinkingSphinx::Index::FauxColumn.new(assoc, *args)
255
- end
256
-
257
- # Use this method to generate SQL for your attributes, conditions, etc.
258
- # You can pass in as whatever ActiveRecord::Base.sanitize_sql accepts.
259
- #
260
- # where sanitize_sql(["active = ?", true])
261
- # #=> WHERE active = 1
262
- #
263
- def sanitize_sql(*args)
264
- @index.model.send(:sanitize_sql, *args)
265
- end
266
-
267
- private
268
-
269
- def source
270
- @source ||= begin
271
- source = ::ThinkingSphinx::Source.new(@index)
272
- @index.sources << source
273
- source
274
- end
275
- end
276
-
277
- def set_single_property(key, value)
278
- source_options = ::ThinkingSphinx::Configuration::SourceOptions
279
- if source_options.include?(key.to_s)
280
- source.options.merge! key => value
281
- else
282
- @index.local_options.merge! key => value
283
- end
284
- end
285
-
286
- def add_sort_attribute(field, options)
287
- add_internal_attribute field, options, "_sort"
288
- end
289
-
290
- def add_facet_attribute(property, options)
291
- add_internal_attribute property, options, "_facet", true
292
- @index.model.sphinx_facets << property.to_facet
293
- end
294
-
295
- def add_internal_attribute(property, options, suffix, crc = false)
296
- return unless ::ThinkingSphinx::Facet.translate?(property)
297
-
298
- ::ThinkingSphinx::Attribute.new(source,
299
- property.columns.collect { |col| col.clone },
300
- options.merge(
301
- :type => property.is_a?(::ThinkingSphinx::Field) ? :string : options[:type],
302
- :as => property.unique_name.to_s.concat(suffix).to_sym,
303
- :crc => crc
304
- ).except(:facet)
305
- )
306
- end
307
-
308
- def no_fields?
309
- @index.sources.empty? || @index.sources.any? { |source|
310
- source.fields.length == 0
311
- }
312
- end
313
- end
314
- end
315
- end
@@ -1,118 +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
- def __path
46
- @stack + [@name]
47
- end
48
-
49
- # Returns true if the stack is empty *and* if the name is a string -
50
- # which is an indication that of raw SQL, as opposed to a value from a
51
- # table's column.
52
- #
53
- def is_string?
54
- @name.is_a?(String) && @stack.empty?
55
- end
56
-
57
- def to_ary
58
- [self]
59
- end
60
-
61
- # This handles any 'invalid' method calls and sets them as the name,
62
- # and pushing the previous name into the stack. The object returns
63
- # itself.
64
- #
65
- # If there's a single argument, it becomes the name, and the method
66
- # symbol goes into the stack as well. Multiple arguments means new
67
- # columns with the original stack and new names (from each argument) gets
68
- # returned.
69
- #
70
- # Easier to explain with examples:
71
- #
72
- # col = FauxColumn.new :a, :b, :c
73
- # col.__name #=> :c
74
- # col.__stack #=> [:a, :b]
75
- #
76
- # col.whatever #=> col
77
- # col.__name #=> :whatever
78
- # col.__stack #=> [:a, :b, :c]
79
- #
80
- # col.something(:id) #=> col
81
- # col.__name #=> :id
82
- # col.__stack #=> [:a, :b, :c, :whatever, :something]
83
- #
84
- # cols = col.short(:x, :y, :z)
85
- # cols[0].__name #=> :x
86
- # cols[0].__stack #=> [:a, :b, :c, :whatever, :something, :short]
87
- # cols[1].__name #=> :y
88
- # cols[1].__stack #=> [:a, :b, :c, :whatever, :something, :short]
89
- # cols[2].__name #=> :z
90
- # cols[2].__stack #=> [:a, :b, :c, :whatever, :something, :short]
91
- #
92
- # Also, this allows method chaining to build up a relevant stack:
93
- #
94
- # col = FauxColumn.new :a, :b
95
- # col.__name #=> :b
96
- # col.__stack #=> [:a]
97
- #
98
- # col.one.two.three #=> col
99
- # col.__name #=> :three
100
- # col.__stack #=> [:a, :b, :one, :two]
101
- #
102
- def method_missing(method, *args)
103
- @stack << @name
104
- @name = method
105
-
106
- if (args.empty?)
107
- self
108
- elsif (args.length == 1)
109
- method_missing(args.first)
110
- else
111
- args.collect { |arg|
112
- FauxColumn.new(@stack + [@name, arg])
113
- }
114
- end
115
- end
116
- end
117
- end
118
- end
@@ -1,37 +0,0 @@
1
- module ThinkingSphinx
2
- class Join
3
- attr_accessor :source, :column, :associations
4
-
5
- def initialize(source, column)
6
- @source = source
7
- @column = column
8
-
9
- @associations = association_stack(column.__path.clone).each { |assoc|
10
- assoc.join_to(source.base)
11
- }
12
-
13
- source.joins << self
14
- end
15
-
16
- private
17
-
18
- # Gets a stack of associations for a specific path.
19
- #
20
- def association_stack(path, parent = nil)
21
- assocs = []
22
-
23
- if parent.nil?
24
- assocs = @source.association(path.shift)
25
- else
26
- assocs = parent.children(path.shift)
27
- end
28
-
29
- until path.empty?
30
- point = path.shift
31
- assocs = assocs.collect { |assoc| assoc.children(point) }.flatten
32
- end
33
-
34
- assocs
35
- end
36
- end
37
- end