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,163 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class CustomAdapter < ThinkingSphinx::AbstractAdapter
4
- #
5
- end
6
-
7
- describe ThinkingSphinx::AbstractAdapter do
8
- describe '.detect' do
9
- let(:model) { stub('model') }
10
-
11
- it "returns a MysqlAdapter object for :mysql" do
12
- ThinkingSphinx::AbstractAdapter.stub(:adapter_for_model => :mysql)
13
-
14
- adapter = ThinkingSphinx::AbstractAdapter.detect(model)
15
- adapter.should be_a(ThinkingSphinx::MysqlAdapter)
16
- end
17
-
18
- it "returns a PostgreSQLAdapter object for :postgresql" do
19
- ThinkingSphinx::AbstractAdapter.stub(:adapter_for_model => :postgresql)
20
-
21
- adapter = ThinkingSphinx::AbstractAdapter.detect(model)
22
- adapter.should be_a(ThinkingSphinx::PostgreSQLAdapter)
23
- end
24
-
25
- it "instantiates the provided class if one is provided" do
26
- ThinkingSphinx::AbstractAdapter.stub(:adapter_for_model => CustomAdapter)
27
- CustomAdapter.should_receive(:new).and_return(stub('adapter'))
28
-
29
- ThinkingSphinx::AbstractAdapter.detect(model)
30
- end
31
-
32
- it "raises an exception for other responses" do
33
- ThinkingSphinx::AbstractAdapter.stub(:adapter_for_model => :sqlite)
34
-
35
- lambda {
36
- ThinkingSphinx::AbstractAdapter.detect(model)
37
- }.should raise_error
38
- end
39
- end
40
-
41
- describe '.adapter_for_model' do
42
- let(:model) { stub('model') }
43
-
44
- after :each do
45
- ThinkingSphinx.database_adapter = nil
46
- end
47
-
48
- it "translates strings to symbols" do
49
- ThinkingSphinx.database_adapter = 'foo'
50
-
51
- ThinkingSphinx::AbstractAdapter.adapter_for_model(model).should == :foo
52
- end
53
-
54
- it "passes through symbols unchanged" do
55
- ThinkingSphinx.database_adapter = :bar
56
-
57
- ThinkingSphinx::AbstractAdapter.adapter_for_model(model).should == :bar
58
- end
59
-
60
- it "returns standard_adapter_for_model if database_adapter is not set" do
61
- ThinkingSphinx.database_adapter = nil
62
- ThinkingSphinx::AbstractAdapter.stub!(:standard_adapter_for_model => :baz)
63
-
64
- ThinkingSphinx::AbstractAdapter.adapter_for_model(model).should == :baz
65
- end
66
-
67
- it "calls the lambda and returns it if one is provided" do
68
- ThinkingSphinx.database_adapter = lambda { |model| :foo }
69
-
70
- ThinkingSphinx::AbstractAdapter.adapter_for_model(model).should == :foo
71
- end
72
- end
73
-
74
- describe '.standard_adapter_for_model' do
75
- let(:klass) { stub('connection class') }
76
- let(:connection) { stub('connection', :class => klass) }
77
- let(:model) { stub('model', :connection => connection) }
78
-
79
- it "translates a normal MySQL adapter" do
80
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::MysqlAdapter')
81
-
82
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
83
- should == :mysql
84
- end
85
-
86
- it "translates a MySQL plus adapter" do
87
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::MysqlplusAdapter')
88
-
89
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
90
- should == :mysql
91
- end
92
-
93
- it "translates a MySQL2 adapter" do
94
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::Mysql2Adapter')
95
-
96
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
97
- should == :mysql
98
- end
99
-
100
- it "translates a NullDB adapter to MySQL" do
101
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::NullDBAdapter')
102
-
103
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
104
- should == :mysql
105
- end
106
-
107
- it "translates a normal PostgreSQL adapter" do
108
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter')
109
-
110
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
111
- should == :postgresql
112
- end
113
-
114
- it "translates a JDBC MySQL adapter to MySQL" do
115
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
116
- connection.stub(:config => {:adapter => 'jdbcmysql'})
117
-
118
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
119
- should == :mysql
120
- end
121
-
122
- it "translates a JDBC PostgreSQL adapter to PostgreSQL" do
123
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
124
- connection.stub(:config => {:adapter => 'jdbcpostgresql'})
125
-
126
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
127
- should == :postgresql
128
- end
129
-
130
- it "translates a JDBC adapter with MySQL connection string to MySQL" do
131
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
132
- connection.stub(:config => {:adapter => 'jdbc',
133
- :url => 'jdbc:mysql://127.0.0.1:3306/sphinx'})
134
-
135
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
136
- should == :mysql
137
- end
138
-
139
- it "translates a JDBC adapter with PostgresSQL connection string to PostgresSQL" do
140
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
141
- connection.stub(:config => {:adapter => 'jdbc',
142
- :url => 'jdbc:postgresql://127.0.0.1:3306/sphinx'})
143
-
144
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
145
- should == :postgresql
146
- end
147
-
148
- it "returns other JDBC adapters without translation" do
149
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::JdbcAdapter')
150
- connection.stub(:config => {:adapter => 'jdbcmssql'})
151
-
152
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
153
- should == :jdbcmssql
154
- end
155
-
156
- it "returns other unknown adapters without translation" do
157
- klass.stub(:name => 'ActiveRecord::ConnectionAdapters::FooAdapter')
158
-
159
- ThinkingSphinx::AbstractAdapter.standard_adapter_for_model(model).
160
- should == 'ActiveRecord::ConnectionAdapters::FooAdapter'
161
- end
162
- end
163
- end
@@ -1,250 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ThinkingSphinx::Association do
4
- describe '.children' do
5
- before :each do
6
- @normal_reflection = stub('reflection', :options => {
7
- :polymorphic => false
8
- })
9
- @normal_association = ThinkingSphinx::Association.new(nil, nil)
10
- @poly_reflection = stub('reflection',
11
- :options => {:polymorphic => true},
12
- :macro => :has_many,
13
- :name => 'polly',
14
- :active_record => 'AR'
15
- )
16
- @non_poly_reflection = stub('reflection', :name => 'non_polly')
17
-
18
- Person.stub!(:reflect_on_association => @normal_reflection)
19
- ThinkingSphinx::Association.stub!(
20
- :new => @normal_association,
21
- :polymorphic_classes => [Person, Person],
22
- :casted_options => {:casted => :options}
23
- )
24
- ::ActiveRecord::Reflection::AssociationReflection.stub!(
25
- :new => @non_poly_reflection
26
- )
27
- end
28
-
29
- it "should return an empty array if no association exists" do
30
- Person.stub!(:reflect_on_association => nil)
31
-
32
- ThinkingSphinx::Association.children(Person, :assoc).should == []
33
- end
34
-
35
- it "should return a single association instance in an array if assocation isn't polymorphic" do
36
- ThinkingSphinx::Association.children(Person, :assoc).should == [@normal_association]
37
- end
38
-
39
- it "should return multiple association instances for polymorphic associations" do
40
- Person.stub!(:reflect_on_association => @poly_reflection)
41
-
42
- ThinkingSphinx::Association.children(Person, :assoc).should ==
43
- [@normal_association, @normal_association]
44
- end
45
-
46
- it "should generate non-polymorphic 'casted' associations for each polymorphic possibility" do
47
- reflections = double('reflections', :[]= => nil)
48
- Person.stub!(:reflections => reflections)
49
-
50
- Person.should_receive(:reflect_on_association).once.
51
- and_return(@poly_reflection)
52
- reflections.should_receive(:[]).with(:polly_Person).twice.and_return(nil)
53
- ThinkingSphinx::Association.should_receive(:casted_options).with(
54
- Person, @poly_reflection
55
- ).twice
56
- ::ActiveRecord::Reflection::AssociationReflection.should_receive(:new).
57
- with(:has_many, :polly_Person, {:casted => :options}, "AR").twice.
58
- and_return(@non_poly_reflection)
59
- ThinkingSphinx::Association.should_receive(:new).with(
60
- nil, @non_poly_reflection
61
- ).twice
62
-
63
- ThinkingSphinx::Association.children(Person, :assoc)
64
- end
65
-
66
- it "should use existing non-polymorphic 'casted' associations" do
67
- reflections = double('reflections', :[]= => nil)
68
- Person.stub!(:reflections => reflections)
69
-
70
- Person.stub!(:reflect_on_association).once.
71
- and_return(@poly_reflection)
72
- reflections.should_receive(:[]).with(:polly_Person).twice.
73
- and_return(nil, @non_poly_reflection)
74
- ThinkingSphinx::Association.should_receive(:casted_options).with(
75
- Person, @poly_reflection
76
- ).once
77
- ::ActiveRecord::Reflection::AssociationReflection.should_receive(:new).
78
- with(:has_many, :polly_Person, {:casted => :options}, "AR").once.
79
- and_return(@non_poly_reflection)
80
- ThinkingSphinx::Association.should_receive(:new).with(
81
- nil, @non_poly_reflection
82
- ).twice
83
-
84
- ThinkingSphinx::Association.children(Person, :assoc)
85
- end
86
- end
87
-
88
- describe '#children' do
89
- before :each do
90
- @reflection = stub('reflection', :klass => :klass)
91
- @association = ThinkingSphinx::Association.new(nil, @reflection)
92
- ThinkingSphinx::Association.stub!(:children => :result)
93
- end
94
-
95
- it "should return the children associations for the given association" do
96
- @association.children(:assoc).should == :result
97
- end
98
-
99
- it "should request children for the reflection klass" do
100
- ThinkingSphinx::Association.should_receive(:children).
101
- with(:klass, :assoc, @association)
102
-
103
- @association.children(:assoc)
104
- end
105
- end
106
-
107
- describe '#join_to' do
108
- before :each do
109
- @parent_join = stub('join assoc').as_null_object
110
- @join = stub('join assoc').as_null_object
111
- @parent = ThinkingSphinx::Association.new(nil, nil)
112
- @parent.stub!(:join_to => true, :join => nil)
113
- @base_join = stub('base join', :joins => [:a, :b, :c])
114
-
115
- if ThinkingSphinx.rails_3_1?
116
- ::ActiveRecord::Associations::JoinDependency::JoinAssociation.stub!(:new => @join)
117
- else
118
- ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation.stub!(:new => @join)
119
- end
120
- end
121
-
122
- it "should call the parent's join_to if parent has no join" do
123
- @assoc = ThinkingSphinx::Association.new(@parent, :ref)
124
- @parent.should_receive(:join_to).with(@base_join)
125
-
126
- @assoc.join_to(@base_join)
127
- end
128
-
129
- it "should not call the parent's join_to if it already has a join" do
130
- @assoc = ThinkingSphinx::Association.new(@parent, :ref)
131
- @parent.stub!(:join => @parent_join)
132
- @parent.should_not_receive(:join_to)
133
-
134
- @assoc.join_to(@base_join)
135
- end
136
-
137
- it "should define the join association with a JoinAssociation instance" do
138
- @assoc = ThinkingSphinx::Association.new(@parent, :ref)
139
-
140
- @assoc.join_to(@base_join).should == @join
141
- @assoc.join.should == @join
142
- end
143
- end
144
-
145
- describe '#is_many?' do
146
- before :each do
147
- @parent = stub('assoc', :is_many? => :parent_is_many)
148
- @reflection = stub('reflection', :macro => :has_many)
149
- end
150
-
151
- it "should return true if association is either a has_many or a habtm" do
152
- association = ThinkingSphinx::Association.new(@parent, @reflection)
153
- association.is_many?.should be_true
154
-
155
- @reflection.stub!(:macro => :has_and_belongs_to_many)
156
- association.is_many?.should be_true
157
- end
158
-
159
- it "should return the parent value if not a has many or habtm and there is a parent" do
160
- association = ThinkingSphinx::Association.new(@parent, @reflection)
161
- @reflection.stub!(:macro => :belongs_to)
162
- association.is_many?.should == :parent_is_many
163
- end
164
-
165
- it "should return false if no parent and not a has many or habtm" do
166
- association = ThinkingSphinx::Association.new(nil, @reflection)
167
- @reflection.stub!(:macro => :belongs_to)
168
- association.is_many?.should be_false
169
- end
170
- end
171
-
172
- describe '#ancestors' do
173
- it "should return an array of associations - including all parents" do
174
- parent = stub('assoc', :ancestors => [:all, :ancestors])
175
- association = ThinkingSphinx::Association.new(parent, @reflection)
176
- association.ancestors.should == [:all, :ancestors, association]
177
- end
178
- end
179
-
180
- describe '.polymorphic_classes' do
181
- it "should return all the polymorphic result types as classes" do
182
- Person.connection.stub!(:select_all => [
183
- {"person_type" => "Person"},
184
- {"person_type" => "Friendship"}
185
- ])
186
- ref = stub('ref',
187
- :active_record => Person,
188
- :options => {:foreign_type => "person_type"}
189
- )
190
- ref.stub!(:foreign_type => "person_type") if ThinkingSphinx.rails_3_1?
191
-
192
- ThinkingSphinx::Association.send(:polymorphic_classes, ref).should == [Person, Friendship]
193
- end
194
- end
195
-
196
- describe '.casted_options' do
197
- before :each do
198
- @options = {
199
- :foreign_key => "thing_id",
200
- :foreign_type => "thing_type",
201
- :polymorphic => true
202
- }
203
- @reflection = stub('assoc reflection', :options => @options)
204
- @reflection.stub!(:foreign_type => "thing_type") if ThinkingSphinx.rails_3_1?
205
- end
206
-
207
- it "should return a new options set for a specific class" do
208
- ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
209
- :polymorphic => nil,
210
- :class_name => "Person",
211
- :foreign_key => "thing_id",
212
- :foreign_type => "thing_type",
213
- :conditions => "::ts_join_alias::.`thing_type` = 'Person'"
214
- }
215
- end
216
-
217
- it "should append to existing Array of conditions" do
218
- @options[:conditions] = ["first condition"]
219
- ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
220
- :polymorphic => nil,
221
- :class_name => "Person",
222
- :foreign_key => "thing_id",
223
- :foreign_type => "thing_type",
224
- :conditions => ["first condition", "::ts_join_alias::.`thing_type` = 'Person'"]
225
- }
226
- end
227
-
228
- it "should merge to an existing Hash of conditions" do
229
- @options[:conditions] = {"field" => "value"}
230
- ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
231
- :polymorphic => nil,
232
- :class_name => "Person",
233
- :foreign_key => "thing_id",
234
- :foreign_type => "thing_type",
235
- :conditions => {"field" => "value", "thing_type" => "Person"}
236
- }
237
- end
238
-
239
- it "should append to an existing String of conditions" do
240
- @options[:conditions] = "first condition"
241
- ThinkingSphinx::Association.send(:casted_options, Person, @reflection).should == {
242
- :polymorphic => nil,
243
- :class_name => "Person",
244
- :foreign_key => "thing_id",
245
- :foreign_type => "thing_type",
246
- :conditions => "first condition AND ::ts_join_alias::.`thing_type` = 'Person'"
247
- }
248
- end
249
- end
250
- end
@@ -1,552 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ThinkingSphinx::Attribute do
4
- before :each do
5
- @index = ThinkingSphinx::Index.new(Person)
6
- @source = ThinkingSphinx::Source.new(@index)
7
-
8
- @index.delta_object = ThinkingSphinx::Deltas::DefaultDelta.new @index, @index.local_options
9
- end
10
-
11
- describe '#initialize' do
12
- it 'raises if no columns are provided so that configuration errors are easier to track down' do
13
- lambda {
14
- ThinkingSphinx::Attribute.new(@source, [])
15
- }.should raise_error(RuntimeError)
16
- end
17
-
18
- it 'raises if an element of the columns param is an integer - as happens when you use id instead of :id - so that configuration errors are easier to track down' do
19
- lambda {
20
- ThinkingSphinx::Attribute.new(@source, [1234])
21
- }.should raise_error(RuntimeError)
22
- end
23
- end
24
-
25
- describe '#unique_name' do
26
- before :each do
27
- @attribute = ThinkingSphinx::Attribute.new @source, [
28
- stub('column', :__stack => [], :__name => "col_name")
29
- ]
30
- end
31
-
32
- it "should use the alias if there is one" do
33
- @attribute.alias = "alias"
34
- @attribute.unique_name.should == "alias"
35
- end
36
-
37
- it "should use the alias if there's multiple columns" do
38
- @attribute.columns << stub('column', :__stack => [], :__name => "col_name")
39
- @attribute.unique_name.should be_nil
40
-
41
- @attribute.alias = "alias"
42
- @attribute.unique_name.should == "alias"
43
- end
44
-
45
- it "should use the column name if there's no alias and just one column" do
46
- @attribute.unique_name.should == "col_name"
47
- end
48
- end
49
-
50
- describe '#to_select_sql' do
51
- it "should convert a mixture of dates and datetimes to timestamps" do
52
- attribute = ThinkingSphinx::Attribute.new(@source,
53
- [ ThinkingSphinx::Index::FauxColumn.new(:created_at),
54
- ThinkingSphinx::Index::FauxColumn.new(:created_on) ],
55
- :as => :times
56
- )
57
- attribute.model = Friendship
58
-
59
- attribute.to_select_sql.should == "CONCAT_WS(',', UNIX_TIMESTAMP(`friendships`.`created_at`), UNIX_TIMESTAMP(`friendships`.`created_on`)) AS `times`"
60
- end
61
-
62
- it "should handle columns which don't exist for polymorphic joins" do
63
- attribute = ThinkingSphinx::Attribute.new(@source,
64
- [ ThinkingSphinx::Index::FauxColumn.new(:team, :name),
65
- ThinkingSphinx::Index::FauxColumn.new(:team, :league) ],
66
- :as => :team
67
- )
68
-
69
- attribute.to_select_sql.should == "CONCAT_WS(' ', IFNULL(`cricket_teams`.`name`, ''), IFNULL(`football_teams`.`name`, ''), IFNULL(`football_teams`.`league`, '')) AS `team`"
70
- end
71
-
72
- it "should return nil if polymorphic association data does not exist" do
73
- attribute = ThinkingSphinx::Attribute.new(@source,
74
- [ThinkingSphinx::Index::FauxColumn.new(:source, :id)],
75
- :as => :source_id, :type => :integer
76
- )
77
-
78
- attribute.to_select_sql.should be_nil
79
- end
80
- end
81
-
82
- describe '#is_many?' do
83
- before :each do
84
- @assoc_a = ThinkingSphinx::Association.new(nil, nil)
85
- @assoc_b = ThinkingSphinx::Association.new(nil, nil)
86
- @assoc_c = ThinkingSphinx::Association.new(nil, nil)
87
-
88
- @attribute = ThinkingSphinx::Attribute.new(
89
- @source, [ThinkingSphinx::Index::FauxColumn.new(:col_name)]
90
- )
91
- @attribute.associations = {
92
- :a => @assoc_a, :b => @assoc_b, :c => @assoc_c
93
- }
94
- @attribute.associations.values.each { |assoc|
95
- assoc.stub!(:is_many? => true)
96
- }
97
- end
98
-
99
- it "should return true if all associations return true to is_many?" do
100
- @attribute.send(:is_many?).should be_true
101
- end
102
-
103
- it "should return true if one association returns true to is_many?" do
104
- @assoc_b.stub!(:is_many? => false)
105
- @assoc_c.stub!(:is_many? => false)
106
-
107
- @attribute.send(:is_many?).should be_true
108
- end
109
-
110
- it "should return false if all associations return false to is_many?" do
111
- @assoc_a.stub!(:is_many? => false)
112
- @assoc_b.stub!(:is_many? => false)
113
- @assoc_c.stub!(:is_many? => false)
114
-
115
- @attribute.send(:is_many?).should be_false
116
- end
117
- end
118
-
119
- describe '#is_string?' do
120
- before :each do
121
- @col_a = ThinkingSphinx::Index::FauxColumn.new("a")
122
- @col_b = ThinkingSphinx::Index::FauxColumn.new("b")
123
- @col_c = ThinkingSphinx::Index::FauxColumn.new("c")
124
-
125
- @attribute = ThinkingSphinx::Attribute.new(
126
- @source, [@col_a, @col_b, @col_c]
127
- )
128
- end
129
-
130
- it "should return true if all columns return true to is_string?" do
131
- @attribute.send(:is_string?).should be_true
132
- end
133
-
134
- it "should return false if one column returns true to is_string?" do
135
- @col_a.send(:instance_variable_set, :@name, :a)
136
- @attribute.send(:is_string?).should be_false
137
- end
138
-
139
- it "should return false if all columns return false to is_string?" do
140
- @col_a.send(:instance_variable_set, :@name, :a)
141
- @col_b.send(:instance_variable_set, :@name, :b)
142
- @col_c.send(:instance_variable_set, :@name, :c)
143
- @attribute.send(:is_string?).should be_false
144
- end
145
- end
146
-
147
- describe '#type' do
148
- before :each do
149
- @column = ThinkingSphinx::Index::FauxColumn.new(:col_name)
150
- @attribute = ThinkingSphinx::Attribute.new(@source, [@column])
151
- @attribute.model = Person
152
- @attribute.stub!(:is_many? => false)
153
- end
154
-
155
- it "should return :multi if is_many? is true" do
156
- @attribute.stub!(:is_many? => true)
157
- @attribute.send(:type).should == :multi
158
- end
159
-
160
- it "should return :string if there's more than one association" do
161
- @attribute.associations = {:a => [:assoc], :b => [:assoc]}
162
- @attribute.send(:type).should == :string
163
- end
164
-
165
- it "should return the column type from the database if not :multi or more than one association" do
166
- @column.send(:instance_variable_set, :@name, "birthday")
167
- @attribute.type.should == :datetime
168
-
169
- @attribute.send(:instance_variable_set, :@type, nil)
170
- @column.send(:instance_variable_set, :@name, "first_name")
171
- @attribute.type.should == :string
172
-
173
- @attribute.send(:instance_variable_set, :@type, nil)
174
- @column.send(:instance_variable_set, :@name, "id")
175
- @attribute.type.should == :integer
176
- end
177
-
178
- it "should return :multi if the columns return multiple datetimes" do
179
- @attribute.stub!(:is_many? => true)
180
- @attribute.stub!(:all_datetimes? => true)
181
-
182
- @attribute.type.should == :multi
183
- end
184
-
185
- it "should return :bigint for 64bit integers" do
186
- Person.columns.detect { |col|
187
- col.name == 'id'
188
- }.stub!(:sql_type => 'BIGINT(20)')
189
- @column.send(:instance_variable_set, :@name, 'id')
190
-
191
- @attribute.type.should == :bigint
192
- end
193
- end
194
-
195
- describe '#all_ints?' do
196
- it "should return true if all columns are integers" do
197
- attribute = ThinkingSphinx::Attribute.new(@source,
198
- [ ThinkingSphinx::Index::FauxColumn.new(:id),
199
- ThinkingSphinx::Index::FauxColumn.new(:team_id) ]
200
- )
201
- attribute.model = Person
202
- attribute.columns.each { |col| attribute.associations[col] = [] }
203
-
204
- attribute.should be_all_ints
205
- end
206
-
207
- it "should return false if only some columns are integers" do
208
- attribute = ThinkingSphinx::Attribute.new(@source,
209
- [ ThinkingSphinx::Index::FauxColumn.new(:id),
210
- ThinkingSphinx::Index::FauxColumn.new(:first_name) ]
211
- )
212
- attribute.model = Person
213
- attribute.columns.each { |col| attribute.associations[col] = [] }
214
-
215
- attribute.should_not be_all_ints
216
- end
217
-
218
- it "should return false if no columns are integers" do
219
- attribute = ThinkingSphinx::Attribute.new(@source,
220
- [ ThinkingSphinx::Index::FauxColumn.new(:first_name),
221
- ThinkingSphinx::Index::FauxColumn.new(:last_name) ]
222
- )
223
- attribute.model = Person
224
- attribute.columns.each { |col| attribute.associations[col] = [] }
225
-
226
- attribute.should_not be_all_ints
227
- end
228
- end
229
-
230
- describe '#all_datetimes?' do
231
- it "should return true if all columns are datetimes" do
232
- attribute = ThinkingSphinx::Attribute.new(@source,
233
- [ ThinkingSphinx::Index::FauxColumn.new(:created_at),
234
- ThinkingSphinx::Index::FauxColumn.new(:updated_at) ]
235
- )
236
- attribute.model = Friendship
237
- attribute.columns.each { |col| attribute.associations[col] = [] }
238
-
239
- attribute.should be_all_datetimes
240
- end
241
-
242
- it "should return false if only some columns are datetimes" do
243
- attribute = ThinkingSphinx::Attribute.new(@source,
244
- [ ThinkingSphinx::Index::FauxColumn.new(:id),
245
- ThinkingSphinx::Index::FauxColumn.new(:created_at) ]
246
- )
247
- attribute.model = Friendship
248
- attribute.columns.each { |col| attribute.associations[col] = [] }
249
-
250
- attribute.should_not be_all_datetimes
251
- end
252
-
253
- it "should return true if all columns can be " do
254
- attribute = ThinkingSphinx::Attribute.new(@source,
255
- [ ThinkingSphinx::Index::FauxColumn.new(:created_at),
256
- ThinkingSphinx::Index::FauxColumn.new(:created_on) ]
257
- )
258
- attribute.model = Friendship
259
- attribute.columns.each { |col| attribute.associations[col] = [] }
260
-
261
- attribute.should be_all_datetimes
262
- end
263
- end
264
-
265
- describe '#all_strings?' do
266
- it "should return true if all columns are strings or text" do
267
- attribute = ThinkingSphinx::Attribute.new(@source,
268
- [ ThinkingSphinx::Index::FauxColumn.new(:first_name),
269
- ThinkingSphinx::Index::FauxColumn.new(:last_name) ]
270
- )
271
- attribute.model = Person
272
- attribute.columns.each { |col| attribute.associations[col] = [] }
273
-
274
- attribute.should be_all_strings
275
- end
276
-
277
- it "should return false if only some columns are strings" do
278
- attribute = ThinkingSphinx::Attribute.new(@source,
279
- [ ThinkingSphinx::Index::FauxColumn.new(:id),
280
- ThinkingSphinx::Index::FauxColumn.new(:first_name) ]
281
- )
282
- attribute.model = Person
283
- attribute.columns.each { |col| attribute.associations[col] = [] }
284
-
285
- attribute.should_not be_all_strings
286
- end
287
-
288
- it "should return true if all columns are not strings" do
289
- attribute = ThinkingSphinx::Attribute.new(@source,
290
- [ ThinkingSphinx::Index::FauxColumn.new(:id),
291
- ThinkingSphinx::Index::FauxColumn.new(:parent_id) ]
292
- )
293
- attribute.model = Person
294
- attribute.columns.each { |col| attribute.associations[col] = [] }
295
-
296
- attribute.should_not be_all_strings
297
- end
298
- end
299
-
300
- describe "MVA with source query" do
301
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
302
- [ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
303
- :as => :tag_ids, :source => :query)
304
- }
305
- let(:adapter) { attribute.send(:adapter) }
306
-
307
- it "should use a query" do
308
- attribute.type_to_config.should == :sql_attr_multi
309
-
310
- declaration, query = attribute.config_value.split('; ')
311
- declaration.should == "uint tag_ids from query"
312
- query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags`"
313
- end
314
- end
315
-
316
- describe "MVA with source query for a delta source" do
317
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
318
- [ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
319
- :as => :tag_ids, :source => :query)
320
- }
321
- let(:adapter) { attribute.send(:adapter) }
322
-
323
- it "should use a query" do
324
- attribute.type_to_config.should == :sql_attr_multi
325
-
326
- declaration, query = attribute.config_value(nil, true).split('; ')
327
- declaration.should == "uint tag_ids from query"
328
- query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` IN (SELECT `id` FROM `people` WHERE `people`.`delta` = 1)"
329
- end
330
- end
331
-
332
- describe "MVA via a HABTM association with a source query" do
333
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
334
- [ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
335
- :as => :link_ids, :source => :query)
336
- }
337
- let(:adapter) { attribute.send(:adapter) }
338
-
339
- it "should use a ranged query" do
340
- attribute.type_to_config.should == :sql_attr_multi
341
-
342
- declaration, query = attribute.config_value.split('; ')
343
- declaration.should == "uint link_ids from query"
344
- query.should == "SELECT `links_people`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `links_people`.`link_id` AS `link_ids` FROM `links_people`"
345
- end
346
- end
347
-
348
- describe "MVA with ranged source query" do
349
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
350
- [ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
351
- :as => :tag_ids, :source => :ranged_query)
352
- }
353
- let(:adapter) { attribute.send(:adapter) }
354
-
355
- it "should use a ranged query" do
356
- attribute.type_to_config.should == :sql_attr_multi
357
-
358
- declaration, query, range_query = attribute.config_value.split('; ')
359
- declaration.should == "uint tag_ids from ranged-query"
360
- query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
361
- range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
362
- end
363
- end
364
-
365
- describe "MVA with ranged source query for a delta source" do
366
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
367
- [ThinkingSphinx::Index::FauxColumn.new(:tags, :id)],
368
- :as => :tag_ids, :source => :ranged_query)
369
- }
370
- let(:adapter) { attribute.send(:adapter) }
371
-
372
- it "should use a ranged query" do
373
- attribute.type_to_config.should == :sql_attr_multi
374
-
375
- declaration, query, range_query = attribute.config_value(nil, true).split('; ')
376
- declaration.should == "uint tag_ids from ranged-query"
377
- query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `tags`.`id` AS `tag_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end AND `tags`.`person_id` IN (SELECT `id` FROM `people` WHERE `people`.`delta` = 1)"
378
- range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
379
- end
380
- end
381
-
382
- describe "MVA via a has-many :through with a ranged source query" do
383
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
384
- [ThinkingSphinx::Index::FauxColumn.new(:football_teams, :id)],
385
- :as => :football_team_ids, :source => :ranged_query)
386
- }
387
- let(:adapter) { attribute.send(:adapter) }
388
-
389
- it "should use a ranged query" do
390
- attribute.type_to_config.should == :sql_attr_multi
391
-
392
- declaration, query, range_query = attribute.config_value.split('; ')
393
- declaration.should == "uint football_team_ids from ranged-query"
394
- query.should == "SELECT `tags`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `tags`.`football_team_id` AS `football_team_ids` FROM `tags` WHERE `tags`.`person_id` >= $start AND `tags`.`person_id` <= $end"
395
- range_query.should == "SELECT MIN(`tags`.`person_id`), MAX(`tags`.`person_id`) FROM `tags`"
396
- end
397
- end
398
-
399
- describe "MVA via a has-many :through using a foreign key with a ranged source query" do
400
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
401
- [ThinkingSphinx::Index::FauxColumn.new(:friends, :id)],
402
- :as => :friend_ids, :source => :ranged_query)
403
- }
404
- let(:adapter) { attribute.send(:adapter) }
405
-
406
- it "should use a ranged query" do
407
- attribute.type_to_config.should == :sql_attr_multi
408
-
409
- declaration, query, range_query = attribute.config_value.split('; ')
410
- declaration.should == "uint friend_ids from ranged-query"
411
- query.should == "SELECT `friendships`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `friendships`.`friend_id` AS `friend_ids` FROM `friendships` WHERE `friendships`.`person_id` >= $start AND `friendships`.`person_id` <= $end"
412
- range_query.should == "SELECT MIN(`friendships`.`person_id`), MAX(`friendships`.`person_id`) FROM `friendships`"
413
- end
414
- end
415
-
416
- describe "MVA via a HABTM with a ranged source query" do
417
- let(:attribute) { ThinkingSphinx::Attribute.new(@source,
418
- [ThinkingSphinx::Index::FauxColumn.new(:links, :id)],
419
- :as => :link_ids, :source => :ranged_query)
420
- }
421
- let(:adapter) { attribute.send(:adapter) }
422
-
423
- it "should use a ranged query" do
424
- attribute.type_to_config.should == :sql_attr_multi
425
-
426
- declaration, query, range_query = attribute.config_value.split('; ')
427
- declaration.should == "uint link_ids from ranged-query"
428
- query.should == "SELECT `links_people`.`person_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `links_people`.`link_id` AS `link_ids` FROM `links_people` WHERE `links_people`.`person_id` >= $start AND `links_people`.`person_id` <= $end"
429
- range_query.should == "SELECT MIN(`links_people`.`person_id`), MAX(`links_people`.`person_id`) FROM `links_people`"
430
- end
431
- end
432
-
433
- describe "MVA via two has-many associations with a ranged source query" do
434
- let(:index) { ThinkingSphinx::Index.new(Alpha) }
435
- let(:source) { ThinkingSphinx::Source.new(index) }
436
- let(:attribute) { ThinkingSphinx::Attribute.new(source,
437
- [ThinkingSphinx::Index::FauxColumn.new(:betas, :gammas, :value)],
438
- :as => :gamma_values, :source => :ranged_query)
439
- }
440
- let(:adapter) { attribute.send(:adapter) }
441
-
442
- it "should use a ranged query" do
443
- attribute.type_to_config.should == :sql_attr_multi
444
-
445
- declaration, query, range_query = attribute.config_value.split('; ')
446
- declaration.should == "uint gamma_values from ranged-query"
447
- query.should == "SELECT `betas`.`alpha_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `gammas`.`value` AS `gamma_values` FROM `betas` LEFT OUTER JOIN `gammas` ON `gammas`.`beta_id` = `betas`.`id` WHERE `betas`.`alpha_id` >= $start AND `betas`.`alpha_id` <= $end"
448
- range_query.should == "SELECT MIN(`betas`.`alpha_id`), MAX(`betas`.`alpha_id`) FROM `betas`"
449
- end
450
- end
451
-
452
- describe "MVA via two has-many associations with a ranged source query for a delta source" do
453
- let(:index) { ThinkingSphinx::Index.new(Alpha) }
454
- let(:source) { ThinkingSphinx::Source.new(index) }
455
- let(:attribute) { ThinkingSphinx::Attribute.new(source,
456
- [ThinkingSphinx::Index::FauxColumn.new(:betas, :gammas, :value)],
457
- :as => :gamma_values, :source => :ranged_query)
458
- }
459
- let(:adapter) { attribute.send(:adapter) }
460
-
461
- before :each do
462
- index.delta_object = ThinkingSphinx::Deltas::DefaultDelta.new index, index.local_options
463
- end
464
-
465
- it "should use a ranged query" do
466
- attribute.type_to_config.should == :sql_attr_multi
467
-
468
- declaration, query, range_query = attribute.config_value(nil, true).split('; ')
469
- declaration.should == "uint gamma_values from ranged-query"
470
- query.should == "SELECT `betas`.`alpha_id` #{ThinkingSphinx.unique_id_expression adapter} AS `id`, `gammas`.`value` AS `gamma_values` FROM `betas` LEFT OUTER JOIN `gammas` ON `gammas`.`beta_id` = `betas`.`id` WHERE `betas`.`alpha_id` >= $start AND `betas`.`alpha_id` <= $end AND `betas`.`alpha_id` IN (SELECT `id` FROM `alphas` WHERE `alphas`.`delta` = 1)"
471
- range_query.should == "SELECT MIN(`betas`.`alpha_id`), MAX(`betas`.`alpha_id`) FROM `betas`"
472
- end
473
- end
474
-
475
- describe "with custom queries" do
476
- before :each do
477
- index = CricketTeam.sphinx_indexes.first
478
- @statement = index.sources.first.to_riddle_for_core(0, 0).sql_attr_multi.last
479
- end
480
-
481
- it "should track the query type accordingly" do
482
- @statement.should match(/uint tags from query/)
483
- end
484
-
485
- it "should include the SQL statement" do
486
- @statement.should match(/SELECT cricket_team_id, id FROM tags/)
487
- end
488
- end
489
-
490
- describe '#live_value' do
491
- before :each do
492
- @attribute = ThinkingSphinx::Attribute.new @source, [
493
- stub('column', :__stack => [], :__name => "col_name")
494
- ]
495
- @instance = stub('model')
496
- end
497
-
498
- it "should translate boolean values to integers" do
499
- @instance.stub!(:col_name => true)
500
- @attribute.live_value(@instance).should == 1
501
-
502
- @instance.stub!(:col_name => false)
503
- @attribute.live_value(@instance).should == 0
504
- end
505
-
506
- it "should translate timestamps to integers" do
507
- now = Time.now
508
- @instance.stub!(:col_name => now)
509
- @attribute.live_value(@instance).should == now.to_i
510
- end
511
-
512
- it "should translate dates to timestamp integers" do
513
- today = Date.today
514
- @instance.stub!(:col_name => today)
515
- @attribute.live_value(@instance).should == today.to_time.to_i
516
- end
517
-
518
- it "should translate nils to 0" do
519
- @instance.stub!(:col_name => nil)
520
- @attribute.live_value(@instance).should == 0
521
- end
522
-
523
- it "should return integers as integers" do
524
- @instance.stub!(:col_name => 42)
525
- @attribute.live_value(@instance).should == 42
526
- end
527
-
528
- it "should handle nils in the association chain" do
529
- @attribute = ThinkingSphinx::Attribute.new @source, [
530
- stub('column', :__stack => [:assoc_name], :__name => :id)
531
- ]
532
- @instance.stub!(:assoc_name => nil)
533
- @attribute.live_value(@instance).should == 0
534
- end
535
-
536
- it "should handle association chains" do
537
- @attribute = ThinkingSphinx::Attribute.new @source, [
538
- stub('column', :__stack => [:assoc_name], :__name => :id)
539
- ]
540
- @instance.stub!(:assoc_name => stub('object', :id => 42))
541
- @attribute.live_value(@instance).should == 42
542
- end
543
-
544
- it "should translate crc strings to their integer values" do
545
- @attribute = ThinkingSphinx::Attribute.new @source, [
546
- stub('column', :__stack => [], :__name => "col_name")
547
- ], :crc => true, :type => :string
548
- @instance.stub!(:col_name => 'foo')
549
- @attribute.live_value(@instance).should == 'foo'.to_crc32
550
- end
551
- end
552
- end