thinking-sphinx 2.1.0 → 3.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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