thinking-sphinx 2.1.0 → 3.0.0.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. data/.gitignore +8 -0
  2. data/.travis.yml +13 -0
  3. data/Appraisals +7 -0
  4. data/Gemfile +10 -0
  5. data/HISTORY +2 -267
  6. data/LICENCE +1 -1
  7. data/README.textile +194 -226
  8. data/Rakefile +24 -0
  9. data/gemfiles/.gitignore +1 -0
  10. data/gemfiles/rails_3_1.gemfile +11 -0
  11. data/gemfiles/rails_3_2.gemfile +11 -0
  12. data/lib/thinking-sphinx.rb +1 -1
  13. data/lib/thinking_sphinx.rb +34 -292
  14. data/lib/thinking_sphinx/active_record.rb +22 -383
  15. data/lib/thinking_sphinx/active_record/association.rb +9 -0
  16. data/lib/thinking_sphinx/active_record/association_proxy.rb +68 -0
  17. data/lib/thinking_sphinx/active_record/associations.rb +68 -0
  18. data/lib/thinking_sphinx/active_record/attribute.rb +20 -0
  19. data/lib/thinking_sphinx/active_record/attribute/sphinx_presenter.rb +32 -0
  20. data/lib/thinking_sphinx/active_record/attribute/type.rb +79 -0
  21. data/lib/thinking_sphinx/active_record/attribute/values.rb +18 -0
  22. data/lib/thinking_sphinx/active_record/base.rb +36 -0
  23. data/lib/thinking_sphinx/active_record/callbacks/delete_callbacks.rb +31 -0
  24. data/lib/thinking_sphinx/active_record/callbacks/delta_callbacks.rb +55 -0
  25. data/lib/thinking_sphinx/active_record/callbacks/update_callbacks.rb +59 -0
  26. data/lib/thinking_sphinx/active_record/column.rb +30 -0
  27. data/lib/thinking_sphinx/active_record/database_adapters.rb +51 -0
  28. data/lib/thinking_sphinx/active_record/database_adapters/abstract_adapter.rb +13 -0
  29. data/lib/thinking_sphinx/active_record/database_adapters/mysql_adapter.rb +23 -0
  30. data/lib/thinking_sphinx/active_record/database_adapters/postgresql_adapter.rb +25 -0
  31. data/lib/thinking_sphinx/active_record/field.rb +11 -0
  32. data/lib/thinking_sphinx/active_record/index.rb +55 -0
  33. data/lib/thinking_sphinx/active_record/interpreter.rb +47 -0
  34. data/lib/thinking_sphinx/active_record/log_subscriber.rb +10 -58
  35. data/lib/thinking_sphinx/active_record/property.rb +28 -0
  36. data/lib/thinking_sphinx/active_record/property_sql_presenter.rb +60 -0
  37. data/lib/thinking_sphinx/active_record/sql_builder.rb +159 -0
  38. data/lib/thinking_sphinx/active_record/sql_source.rb +138 -0
  39. data/lib/thinking_sphinx/active_record/sql_source/template.rb +46 -0
  40. data/lib/thinking_sphinx/batched_search.rb +26 -0
  41. data/lib/thinking_sphinx/callbacks.rb +15 -0
  42. data/lib/thinking_sphinx/configuration.rb +80 -331
  43. data/lib/thinking_sphinx/configuration/consistent_ids.rb +31 -0
  44. data/lib/thinking_sphinx/configuration/defaults.rb +5 -0
  45. data/lib/thinking_sphinx/core.rb +6 -0
  46. data/lib/thinking_sphinx/core/index.rb +68 -0
  47. data/lib/thinking_sphinx/core/interpreter.rb +19 -0
  48. data/lib/thinking_sphinx/deltas.rb +35 -26
  49. data/lib/thinking_sphinx/deltas/default_delta.rb +56 -56
  50. data/lib/thinking_sphinx/excerpter.rb +23 -21
  51. data/lib/thinking_sphinx/facet.rb +22 -127
  52. data/lib/thinking_sphinx/facet_search.rb +95 -162
  53. data/lib/thinking_sphinx/index.rb +39 -143
  54. data/lib/thinking_sphinx/index_set.rb +51 -0
  55. data/lib/thinking_sphinx/masks.rb +8 -0
  56. data/lib/thinking_sphinx/masks/group_enumerators_mask.rb +23 -0
  57. data/lib/thinking_sphinx/masks/pagination_mask.rb +60 -0
  58. data/lib/thinking_sphinx/masks/scopes_mask.rb +35 -0
  59. data/lib/thinking_sphinx/masks/weight_enumerator_mask.rb +11 -0
  60. data/lib/thinking_sphinx/middlewares.rb +36 -0
  61. data/lib/thinking_sphinx/middlewares/active_record_translator.rb +73 -0
  62. data/lib/thinking_sphinx/middlewares/geographer.rb +53 -0
  63. data/lib/thinking_sphinx/middlewares/glazier.rb +39 -0
  64. data/lib/thinking_sphinx/middlewares/ids_only.rb +13 -0
  65. data/lib/thinking_sphinx/middlewares/inquirer.rb +62 -0
  66. data/lib/thinking_sphinx/middlewares/middleware.rb +9 -0
  67. data/lib/thinking_sphinx/middlewares/sphinxql.rb +149 -0
  68. data/lib/thinking_sphinx/middlewares/stale_id_checker.rb +45 -0
  69. data/lib/thinking_sphinx/middlewares/stale_id_filter.rb +46 -0
  70. data/lib/thinking_sphinx/panes.rb +8 -0
  71. data/lib/thinking_sphinx/panes/attributes_pane.rb +9 -0
  72. data/lib/thinking_sphinx/panes/distance_pane.rb +13 -0
  73. data/lib/thinking_sphinx/panes/excerpts_pane.rb +37 -0
  74. data/lib/thinking_sphinx/panes/weight_pane.rb +9 -0
  75. data/lib/thinking_sphinx/railtie.rb +6 -40
  76. data/lib/thinking_sphinx/rake_interface.rb +47 -0
  77. data/lib/thinking_sphinx/real_time.rb +11 -0
  78. data/lib/thinking_sphinx/real_time/attribute.rb +5 -0
  79. data/lib/thinking_sphinx/real_time/callbacks/real_time_callbacks.rb +48 -0
  80. data/lib/thinking_sphinx/real_time/field.rb +3 -0
  81. data/lib/thinking_sphinx/real_time/index.rb +47 -0
  82. data/lib/thinking_sphinx/real_time/index/template.rb +33 -0
  83. data/lib/thinking_sphinx/real_time/interpreter.rb +23 -0
  84. data/lib/thinking_sphinx/real_time/property.rb +16 -0
  85. data/lib/thinking_sphinx/scopes.rb +22 -0
  86. data/lib/thinking_sphinx/search.rb +90 -1028
  87. data/lib/thinking_sphinx/search/batch_inquirer.rb +27 -0
  88. data/lib/thinking_sphinx/search/context.rb +26 -0
  89. data/lib/thinking_sphinx/search/glaze.rb +32 -0
  90. data/lib/thinking_sphinx/search/merger.rb +24 -0
  91. data/lib/thinking_sphinx/search/query.rb +43 -0
  92. data/lib/thinking_sphinx/search/stale_ids_exception.rb +11 -0
  93. data/lib/thinking_sphinx/search/translator.rb +50 -0
  94. data/lib/thinking_sphinx/tasks.rb +22 -125
  95. data/lib/thinking_sphinx/test.rb +9 -19
  96. data/sketchpad.rb +58 -0
  97. data/spec/acceptance/association_scoping_spec.rb +23 -0
  98. data/spec/acceptance/attribute_access_spec.rb +39 -0
  99. data/spec/acceptance/attribute_updates_spec.rb +16 -0
  100. data/spec/acceptance/batch_searching_spec.rb +21 -0
  101. data/spec/acceptance/big_integers_spec.rb +27 -0
  102. data/spec/acceptance/excerpts_spec.rb +14 -0
  103. data/spec/acceptance/facets_spec.rb +122 -0
  104. data/spec/acceptance/geosearching_spec.rb +39 -0
  105. data/spec/acceptance/grouping_by_attributes_spec.rb +77 -0
  106. data/spec/acceptance/paginating_search_results_spec.rb +24 -0
  107. data/spec/acceptance/remove_deleted_records_spec.rb +23 -0
  108. data/spec/acceptance/search_counts_spec.rb +18 -0
  109. data/spec/acceptance/search_for_just_ids_spec.rb +19 -0
  110. data/spec/acceptance/searching_across_models_spec.rb +28 -0
  111. data/spec/acceptance/searching_on_fields_spec.rb +56 -0
  112. data/spec/acceptance/searching_with_filters_spec.rb +109 -0
  113. data/spec/acceptance/searching_with_sti_spec.rb +55 -0
  114. data/spec/acceptance/searching_within_a_model_spec.rb +52 -0
  115. data/spec/acceptance/sorting_search_results_spec.rb +41 -0
  116. data/spec/acceptance/spec_helper.rb +4 -0
  117. data/spec/acceptance/specifying_sql_spec.rb +62 -0
  118. data/spec/acceptance/sphinx_scopes_spec.rb +49 -0
  119. data/spec/acceptance/sql_deltas_spec.rb +43 -0
  120. data/spec/acceptance/support/database_cleaner.rb +11 -0
  121. data/spec/acceptance/support/sphinx_controller.rb +39 -0
  122. data/spec/acceptance/support/sphinx_helpers.rb +24 -0
  123. data/spec/acceptance/suspended_deltas_spec.rb +20 -0
  124. data/spec/internal/.gitignore +1 -0
  125. data/spec/internal/app/indices/animal_index.rb +3 -0
  126. data/spec/internal/app/indices/article_index.rb +24 -0
  127. data/spec/internal/app/indices/book_index.rb +8 -0
  128. data/spec/internal/app/indices/city_index.rb +6 -0
  129. data/spec/internal/app/indices/product_index.rb +3 -0
  130. data/spec/internal/app/indices/tee_index.rb +4 -0
  131. data/spec/internal/app/indices/user_index.rb +5 -0
  132. data/spec/internal/app/models/animal.rb +2 -0
  133. data/spec/internal/app/models/article.rb +5 -0
  134. data/spec/internal/app/models/bird.rb +2 -0
  135. data/spec/internal/app/models/book.rb +11 -0
  136. data/spec/internal/app/models/city.rb +2 -0
  137. data/spec/internal/app/models/colour.rb +3 -0
  138. data/spec/internal/app/models/flightless_bird.rb +2 -0
  139. data/spec/internal/app/models/mammal.rb +2 -0
  140. data/spec/internal/app/models/product.rb +3 -0
  141. data/spec/internal/app/models/tag.rb +4 -0
  142. data/{features/thinking_sphinx → spec/internal/app}/models/tagging.rb +1 -1
  143. data/spec/internal/app/models/tee.rb +3 -0
  144. data/spec/internal/app/models/tweet.rb +3 -0
  145. data/spec/internal/app/models/user.rb +3 -0
  146. data/spec/internal/config/database.yml +5 -0
  147. data/spec/internal/db/schema.rb +65 -0
  148. data/spec/internal/log/.gitignore +1 -0
  149. data/spec/spec_helper.rb +8 -49
  150. data/spec/support/sphinx_yaml_helpers.rb +9 -0
  151. data/spec/thinking_sphinx/active_record/association_spec.rb +12 -0
  152. data/spec/thinking_sphinx/active_record/associations_spec.rb +184 -0
  153. data/spec/thinking_sphinx/active_record/attribute/type_spec.rb +147 -0
  154. data/spec/thinking_sphinx/active_record/base_spec.rb +61 -0
  155. data/spec/thinking_sphinx/active_record/callbacks/delete_callbacks_spec.rb +80 -0
  156. data/spec/thinking_sphinx/active_record/callbacks/delta_callbacks_spec.rb +147 -0
  157. data/spec/thinking_sphinx/active_record/callbacks/update_callbacks_spec.rb +69 -0
  158. data/spec/thinking_sphinx/active_record/column_spec.rb +47 -0
  159. data/spec/thinking_sphinx/active_record/database_adapters/abstract_adapter_spec.rb +31 -0
  160. data/spec/thinking_sphinx/active_record/database_adapters/mysql_adapter_spec.rb +43 -0
  161. data/spec/thinking_sphinx/active_record/database_adapters/postgresql_adapter_spec.rb +45 -0
  162. data/spec/thinking_sphinx/active_record/database_adapters_spec.rb +108 -0
  163. data/spec/thinking_sphinx/active_record/field_spec.rb +36 -0
  164. data/spec/thinking_sphinx/active_record/index_spec.rb +208 -0
  165. data/spec/thinking_sphinx/active_record/interpreter_spec.rb +293 -0
  166. data/spec/thinking_sphinx/active_record/property_sql_presenter_spec.rb +162 -0
  167. data/spec/thinking_sphinx/active_record/sql_builder_spec.rb +666 -0
  168. data/spec/thinking_sphinx/active_record/sql_source_spec.rb +401 -0
  169. data/spec/thinking_sphinx/configuration_spec.rb +264 -171
  170. data/spec/thinking_sphinx/deltas/default_delta_spec.rb +116 -0
  171. data/spec/thinking_sphinx/deltas_spec.rb +58 -0
  172. data/spec/thinking_sphinx/excerpter_spec.rb +40 -38
  173. data/spec/thinking_sphinx/facet_search_spec.rb +49 -151
  174. data/spec/thinking_sphinx/index_set_spec.rb +68 -0
  175. data/spec/thinking_sphinx/index_spec.rb +91 -155
  176. data/spec/thinking_sphinx/masks/pagination_mask_spec.rb +121 -0
  177. data/spec/thinking_sphinx/masks/scopes_mask_spec.rb +68 -0
  178. data/spec/thinking_sphinx/middlewares/active_record_translator_spec.rb +132 -0
  179. data/spec/thinking_sphinx/middlewares/geographer_spec.rb +89 -0
  180. data/spec/thinking_sphinx/middlewares/glazier_spec.rb +62 -0
  181. data/spec/thinking_sphinx/middlewares/inquirer_spec.rb +55 -0
  182. data/spec/thinking_sphinx/middlewares/sphinxql_spec.rb +271 -0
  183. data/spec/thinking_sphinx/middlewares/stale_id_checker_spec.rb +47 -0
  184. data/spec/thinking_sphinx/middlewares/stale_id_filter_spec.rb +91 -0
  185. data/spec/thinking_sphinx/panes/attributes_pane_spec.rb +21 -0
  186. data/spec/thinking_sphinx/panes/distance_pane_spec.rb +41 -0
  187. data/spec/thinking_sphinx/panes/excerpts_pane_spec.rb +53 -0
  188. data/spec/thinking_sphinx/panes/weight_pane_spec.rb +20 -0
  189. data/spec/thinking_sphinx/rake_interface_spec.rb +147 -0
  190. data/spec/thinking_sphinx/real_time/attribute_spec.rb +62 -0
  191. data/spec/thinking_sphinx/real_time/callbacks/real_time_callbacks_spec.rb +76 -0
  192. data/spec/thinking_sphinx/real_time/field_spec.rb +54 -0
  193. data/spec/thinking_sphinx/real_time/index_spec.rb +154 -0
  194. data/spec/thinking_sphinx/real_time/interpreter_spec.rb +147 -0
  195. data/spec/thinking_sphinx/scopes_spec.rb +38 -0
  196. data/spec/thinking_sphinx/search/glaze_spec.rb +55 -0
  197. data/spec/thinking_sphinx/search/query_spec.rb +46 -0
  198. data/spec/thinking_sphinx/search_spec.rb +65 -1357
  199. data/spec/thinking_sphinx_spec.rb +19 -182
  200. data/thinking-sphinx.gemspec +33 -0
  201. metadata +318 -431
  202. data/features/abstract_inheritance.feature +0 -10
  203. data/features/alternate_primary_key.feature +0 -27
  204. data/features/attribute_transformation.feature +0 -22
  205. data/features/attribute_updates.feature +0 -79
  206. data/features/deleting_instances.feature +0 -70
  207. data/features/direct_attributes.feature +0 -11
  208. data/features/excerpts.feature +0 -21
  209. data/features/extensible_delta_indexing.feature +0 -9
  210. data/features/facets.feature +0 -88
  211. data/features/facets_across_model.feature +0 -29
  212. data/features/field_sorting.feature +0 -18
  213. data/features/handling_edits.feature +0 -97
  214. data/features/retry_stale_indexes.feature +0 -24
  215. data/features/searching_across_models.feature +0 -20
  216. data/features/searching_by_index.feature +0 -41
  217. data/features/searching_by_model.feature +0 -175
  218. data/features/searching_with_find_arguments.feature +0 -56
  219. data/features/sphinx_detection.feature +0 -25
  220. data/features/sphinx_scopes.feature +0 -68
  221. data/features/step_definitions/alpha_steps.rb +0 -16
  222. data/features/step_definitions/beta_steps.rb +0 -7
  223. data/features/step_definitions/common_steps.rb +0 -205
  224. data/features/step_definitions/extensible_delta_indexing_steps.rb +0 -7
  225. data/features/step_definitions/facet_steps.rb +0 -96
  226. data/features/step_definitions/find_arguments_steps.rb +0 -36
  227. data/features/step_definitions/gamma_steps.rb +0 -15
  228. data/features/step_definitions/scope_steps.rb +0 -19
  229. data/features/step_definitions/search_steps.rb +0 -94
  230. data/features/step_definitions/sphinx_steps.rb +0 -35
  231. data/features/sti_searching.feature +0 -19
  232. data/features/support/env.rb +0 -24
  233. data/features/support/lib/generic_delta_handler.rb +0 -8
  234. data/features/thinking_sphinx/database.example.yml +0 -3
  235. data/features/thinking_sphinx/db/.gitignore +0 -1
  236. data/features/thinking_sphinx/db/fixtures/alphas.rb +0 -8
  237. data/features/thinking_sphinx/db/fixtures/authors.rb +0 -1
  238. data/features/thinking_sphinx/db/fixtures/betas.rb +0 -11
  239. data/features/thinking_sphinx/db/fixtures/boxes.rb +0 -9
  240. data/features/thinking_sphinx/db/fixtures/categories.rb +0 -1
  241. data/features/thinking_sphinx/db/fixtures/cats.rb +0 -3
  242. data/features/thinking_sphinx/db/fixtures/comments.rb +0 -24
  243. data/features/thinking_sphinx/db/fixtures/developers.rb +0 -31
  244. data/features/thinking_sphinx/db/fixtures/dogs.rb +0 -3
  245. data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +0 -10
  246. data/features/thinking_sphinx/db/fixtures/foxes.rb +0 -3
  247. data/features/thinking_sphinx/db/fixtures/gammas.rb +0 -10
  248. data/features/thinking_sphinx/db/fixtures/music.rb +0 -4
  249. data/features/thinking_sphinx/db/fixtures/people.rb +0 -1001
  250. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +0 -1
  251. data/features/thinking_sphinx/db/fixtures/posts.rb +0 -10
  252. data/features/thinking_sphinx/db/fixtures/robots.rb +0 -8
  253. data/features/thinking_sphinx/db/fixtures/tags.rb +0 -27
  254. data/features/thinking_sphinx/db/migrations/create_alphas.rb +0 -8
  255. data/features/thinking_sphinx/db/migrations/create_animals.rb +0 -5
  256. data/features/thinking_sphinx/db/migrations/create_authors.rb +0 -3
  257. data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +0 -6
  258. data/features/thinking_sphinx/db/migrations/create_betas.rb +0 -5
  259. data/features/thinking_sphinx/db/migrations/create_boxes.rb +0 -5
  260. data/features/thinking_sphinx/db/migrations/create_categories.rb +0 -3
  261. data/features/thinking_sphinx/db/migrations/create_comments.rb +0 -10
  262. data/features/thinking_sphinx/db/migrations/create_developers.rb +0 -7
  263. data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +0 -5
  264. data/features/thinking_sphinx/db/migrations/create_gammas.rb +0 -3
  265. data/features/thinking_sphinx/db/migrations/create_genres.rb +0 -3
  266. data/features/thinking_sphinx/db/migrations/create_music.rb +0 -6
  267. data/features/thinking_sphinx/db/migrations/create_people.rb +0 -13
  268. data/features/thinking_sphinx/db/migrations/create_posts.rb +0 -6
  269. data/features/thinking_sphinx/db/migrations/create_robots.rb +0 -4
  270. data/features/thinking_sphinx/db/migrations/create_taggings.rb +0 -5
  271. data/features/thinking_sphinx/db/migrations/create_tags.rb +0 -4
  272. data/features/thinking_sphinx/models/alpha.rb +0 -23
  273. data/features/thinking_sphinx/models/andrew.rb +0 -17
  274. data/features/thinking_sphinx/models/animal.rb +0 -5
  275. data/features/thinking_sphinx/models/author.rb +0 -3
  276. data/features/thinking_sphinx/models/beta.rb +0 -13
  277. data/features/thinking_sphinx/models/box.rb +0 -8
  278. data/features/thinking_sphinx/models/cat.rb +0 -3
  279. data/features/thinking_sphinx/models/category.rb +0 -4
  280. data/features/thinking_sphinx/models/comment.rb +0 -10
  281. data/features/thinking_sphinx/models/developer.rb +0 -21
  282. data/features/thinking_sphinx/models/dog.rb +0 -3
  283. data/features/thinking_sphinx/models/extensible_beta.rb +0 -9
  284. data/features/thinking_sphinx/models/fox.rb +0 -5
  285. data/features/thinking_sphinx/models/gamma.rb +0 -5
  286. data/features/thinking_sphinx/models/genre.rb +0 -3
  287. data/features/thinking_sphinx/models/medium.rb +0 -5
  288. data/features/thinking_sphinx/models/music.rb +0 -10
  289. data/features/thinking_sphinx/models/person.rb +0 -24
  290. data/features/thinking_sphinx/models/post.rb +0 -22
  291. data/features/thinking_sphinx/models/robot.rb +0 -12
  292. data/features/thinking_sphinx/models/tag.rb +0 -3
  293. data/lib/cucumber/thinking_sphinx/external_world.rb +0 -12
  294. data/lib/cucumber/thinking_sphinx/internal_world.rb +0 -137
  295. data/lib/cucumber/thinking_sphinx/sql_logger.rb +0 -28
  296. data/lib/thinking_sphinx/action_controller.rb +0 -31
  297. data/lib/thinking_sphinx/active_record/attribute_updates.rb +0 -54
  298. data/lib/thinking_sphinx/active_record/collection_proxy.rb +0 -47
  299. data/lib/thinking_sphinx/active_record/collection_proxy_with_scopes.rb +0 -27
  300. data/lib/thinking_sphinx/active_record/delta.rb +0 -67
  301. data/lib/thinking_sphinx/active_record/has_many_association.rb +0 -44
  302. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +0 -21
  303. data/lib/thinking_sphinx/active_record/scopes.rb +0 -110
  304. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +0 -94
  305. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -62
  306. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +0 -188
  307. data/lib/thinking_sphinx/association.rb +0 -230
  308. data/lib/thinking_sphinx/attribute.rb +0 -405
  309. data/lib/thinking_sphinx/auto_version.rb +0 -40
  310. data/lib/thinking_sphinx/bundled_search.rb +0 -40
  311. data/lib/thinking_sphinx/class_facet.rb +0 -20
  312. data/lib/thinking_sphinx/connection.rb +0 -71
  313. data/lib/thinking_sphinx/context.rb +0 -81
  314. data/lib/thinking_sphinx/core/string.rb +0 -15
  315. data/lib/thinking_sphinx/deltas/delete_job.rb +0 -16
  316. data/lib/thinking_sphinx/deltas/index_job.rb +0 -17
  317. data/lib/thinking_sphinx/deploy/capistrano.rb +0 -99
  318. data/lib/thinking_sphinx/field.rb +0 -98
  319. data/lib/thinking_sphinx/index/builder.rb +0 -315
  320. data/lib/thinking_sphinx/index/faux_column.rb +0 -118
  321. data/lib/thinking_sphinx/join.rb +0 -37
  322. data/lib/thinking_sphinx/property.rb +0 -187
  323. data/lib/thinking_sphinx/search_methods.rb +0 -439
  324. data/lib/thinking_sphinx/sinatra.rb +0 -7
  325. data/lib/thinking_sphinx/source.rb +0 -194
  326. data/lib/thinking_sphinx/source/internal_properties.rb +0 -51
  327. data/lib/thinking_sphinx/source/sql.rb +0 -174
  328. data/spec/fixtures/data.sql +0 -32
  329. data/spec/fixtures/database.yml.default +0 -3
  330. data/spec/fixtures/models.rb +0 -164
  331. data/spec/fixtures/structure.sql +0 -146
  332. data/spec/sphinx_helper.rb +0 -60
  333. data/spec/support/rails.rb +0 -25
  334. data/spec/thinking_sphinx/active_record/delta_spec.rb +0 -123
  335. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +0 -173
  336. data/spec/thinking_sphinx/active_record/scopes_spec.rb +0 -177
  337. data/spec/thinking_sphinx/active_record_spec.rb +0 -573
  338. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +0 -163
  339. data/spec/thinking_sphinx/association_spec.rb +0 -250
  340. data/spec/thinking_sphinx/attribute_spec.rb +0 -552
  341. data/spec/thinking_sphinx/auto_version_spec.rb +0 -103
  342. data/spec/thinking_sphinx/connection_spec.rb +0 -77
  343. data/spec/thinking_sphinx/context_spec.rb +0 -127
  344. data/spec/thinking_sphinx/core/array_spec.rb +0 -9
  345. data/spec/thinking_sphinx/core/string_spec.rb +0 -9
  346. data/spec/thinking_sphinx/facet_spec.rb +0 -359
  347. data/spec/thinking_sphinx/field_spec.rb +0 -127
  348. data/spec/thinking_sphinx/index/builder_spec.rb +0 -532
  349. data/spec/thinking_sphinx/index/faux_column_spec.rb +0 -36
  350. data/spec/thinking_sphinx/search_methods_spec.rb +0 -156
  351. data/spec/thinking_sphinx/source_spec.rb +0 -267
  352. data/spec/thinking_sphinx/test_spec.rb +0 -20
@@ -0,0 +1,27 @@
1
+ class ThinkingSphinx::Search::BatchInquirer
2
+ def initialize(&block)
3
+ @queries = []
4
+
5
+ yield self if block_given?
6
+ end
7
+
8
+ def append_query(query)
9
+ @queries << query
10
+ end
11
+
12
+ def results
13
+ @results ||= begin
14
+ @queries.freeze
15
+
16
+ results = [connection.query(@queries.join('; '))]
17
+ results << connection.store_result while connection.next_result
18
+ results
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def connection
25
+ @connection ||= ThinkingSphinx::Configuration.instance.connection
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ class ThinkingSphinx::Search::Context
2
+ attr_reader :search, :configuration
3
+
4
+ def initialize(search, configuration = nil)
5
+ @search = search
6
+ @configuration = configuration || ThinkingSphinx::Configuration.instance
7
+ @memory = {
8
+ :results => [],
9
+ :panes => ThinkingSphinx::Configuration::Defaults::PANES
10
+ }
11
+ end
12
+
13
+ def [](key)
14
+ @memory[key]
15
+ end
16
+
17
+ def []=(key, value)
18
+ @memory[key] = value
19
+ end
20
+
21
+ def log(notification, message, &block)
22
+ ActiveSupport::Notifications.instrument(
23
+ "#{notification}.thinking_sphinx", notification => message, &block
24
+ )
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ class ThinkingSphinx::Search::Glaze < BasicObject
2
+ def initialize(context, object, raw = {}, pane_classes = [])
3
+ @object, @raw = object, raw
4
+
5
+ @panes = pane_classes.collect { |klass|
6
+ klass.new context, object, @raw
7
+ }
8
+ end
9
+
10
+ def ==(object)
11
+ (@object == object) || super
12
+ end
13
+
14
+ def equal?(object)
15
+ @object.equal? object
16
+ end
17
+
18
+ def unglazed
19
+ @object
20
+ end
21
+
22
+ private
23
+
24
+ def method_missing(method, *args, &block)
25
+ if @object.respond_to?(method)
26
+ @object.send(method, *args, &block)
27
+ else
28
+ pane = @panes.detect { |pane| pane.respond_to?(method) }
29
+ pane.nil? ? super : pane.send(method, *args, &block)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ class ThinkingSphinx::Search::Merger
2
+ def initialize(search)
3
+ @search = search
4
+ end
5
+
6
+ def merge!(query = nil, options = {})
7
+ @search.query = query unless query.nil?
8
+ options.each do |key, value|
9
+ case key
10
+ when :conditions, :with, :without, :with_all, :without_all
11
+ @search.options[key] ||= {}
12
+ @search.options[key].merge! value
13
+ when :without_ids, :classes
14
+ @search.options[key] ||= []
15
+ @search.options[key] += value
16
+ @search.options[key].uniq!
17
+ else
18
+ @search.options[key] = value
19
+ end
20
+ end
21
+
22
+ @search
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ class ThinkingSphinx::Search::Query
2
+ if Regexp.instance_methods.include?(:encoding)
3
+ DefaultToken = Regexp.new('\p{Word}+')
4
+ else
5
+ DefaultToken = Regexp.new('\w+', nil, 'u')
6
+ end
7
+
8
+ attr_reader :keywords, :conditions, :star
9
+
10
+ def initialize(keywords = '', conditions = {}, star = false)
11
+ @keywords, @conditions, @star = keywords, conditions, star
12
+ end
13
+
14
+ def to_s
15
+ (star_keyword(keywords) + ' ' + conditions.keys.collect { |key|
16
+ "@#{key} #{star_keyword conditions[key], key}"
17
+ }.join(' ')).strip
18
+ end
19
+
20
+ private
21
+
22
+ def star_keyword(keyword, key = nil)
23
+ unless star && (key.nil? || key.to_s != 'sphinx_internal_class')
24
+ return keyword.to_s
25
+ end
26
+
27
+ token = star.is_a?(Regexp) ? star : DefaultToken
28
+ keyword.gsub(/("#{token}(.*?#{token})?"|(?![!-])#{token})/u) do
29
+ pre, proper, post = $`, $&, $'
30
+ # E.g. "@foo", "/2", "~3", but not as part of a token
31
+ is_operator = pre.match(%r{(\W|^)[@~/]\Z}) ||
32
+ pre.match(%r{(\W|^)@\([^\)]*$})
33
+ # E.g. "foo bar", with quotes
34
+ is_quote = proper[/^".*"$/]
35
+ has_star = post[/\*$/] || pre[/^\*/]
36
+ if is_operator || is_quote || has_star
37
+ proper
38
+ else
39
+ "*#{proper}*"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,11 @@
1
+ class ThinkingSphinx::Search::StaleIdsException < StandardError
2
+ attr_reader :ids
3
+
4
+ def initialize(ids)
5
+ @ids = ids
6
+ end
7
+
8
+ def message
9
+ "Record IDs found by Sphinx but not by ActiveRecord : #{ids.join(', ')}"
10
+ end
11
+ end
@@ -0,0 +1,50 @@
1
+ class ThinkingSphinx::Search::Translator
2
+ attr_reader :raw, :excerpter
3
+
4
+ def initialize(raw, excerpter)
5
+ @raw, @excerpter = raw, excerpter
6
+ end
7
+
8
+ def to_active_record
9
+ results_for_models # load now to avoid segfaults
10
+ raw.collect { |row|
11
+ ThinkingSphinx::Search::Glaze.new result_for(row), excerpter, row
12
+ }
13
+ end
14
+
15
+ private
16
+
17
+ def ids_for_model(model_name)
18
+ raw.select { |row|
19
+ row['sphinx_internal_class'] == model_name
20
+ }.collect { |row|
21
+ row['sphinx_internal_id']
22
+ }
23
+ end
24
+
25
+ def model_names
26
+ @model_names ||= raw.collect { |row|
27
+ row['sphinx_internal_class']
28
+ }.uniq
29
+ end
30
+
31
+ def result_for(row)
32
+ results_for_models[row['sphinx_internal_class']].detect { |record|
33
+ record.id == row['sphinx_internal_id']
34
+ }
35
+ end
36
+
37
+ def results_for_models
38
+ @results_for_models ||= model_names.inject({}) { |hash, name|
39
+ ids = ids_for_model(name)
40
+ hash[name] = name.constantize.where(:id => ids)
41
+
42
+ stale_ids = ids - hash[name].collect(&:id)
43
+ if stale_ids.any?
44
+ raise ThinkingSphinx::Search::StaleIdsException, stale_ids
45
+ end
46
+
47
+ hash
48
+ }
49
+ end
50
+ end
@@ -1,138 +1,35 @@
1
- require 'fileutils'
2
- require 'timeout'
3
-
4
- namespace :thinking_sphinx do
5
- task :app_env do
6
- if defined?(Rails)
7
- Rails.application.require_environment!
8
- Rails.configuration.cache_classes = false
9
- elsif defined?(Merb)
10
- Rake::Task[:merb_env].invoke
11
- elsif defined?(Sinatra)
12
- Sinatra::Application.environment = ENV['RACK_ENV']
13
- end
14
- end
15
-
16
- desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
17
- task :running_start => :app_env do
18
- Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
19
- Rake::Task["thinking_sphinx:start"].invoke
20
- end
21
-
22
- desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
23
- task :start => :app_env do
24
- config = ThinkingSphinx::Configuration.instance
25
-
26
- FileUtils.mkdir_p config.searchd_file_path
27
- raise RuntimeError, "searchd is already running." if sphinx_running?
28
-
29
- Dir["#{config.searchd_file_path}/*.spl"].each { |file| File.delete(file) }
30
-
31
- if ENV["NODETACH"] == "true"
32
- unless pid = fork
33
- config.controller.start(:nodetach => true)
34
- end
35
- Signal.trap('TERM') { Process.kill(:QUIT, pid) }
36
- Signal.trap('INT') { Process.kill(:QUIT, pid) }
37
- Process.wait(pid)
38
- else
39
- config.controller.start
40
-
41
- if sphinx_running?
42
- puts "Started successfully (pid #{sphinx_pid})."
43
- else
44
- puts "Failed to start searchd daemon. Check #{config.searchd_log_file}"
45
- puts "Be sure to run thinking_sphinx:index before thinking_sphinx:start"
46
- end
47
- end
1
+ namespace :ts do
2
+ desc 'The current version of Thinking Sphinx'
3
+ task :version do
4
+ puts "Thinking Sphinx v#{ThinkingSphinx::VERSION}"
48
5
  end
49
6
 
50
- desc "Stop Sphinx using Thinking Sphinx's settings"
51
- task :stop => :app_env do
52
- unless sphinx_running?
53
- puts "searchd is not running"
54
- else
55
- config = ThinkingSphinx::Configuration.instance
56
- pid = sphinx_pid
57
- config.controller.stop
58
-
59
- # Ensure searchd is stopped, but don't try too hard
60
- Timeout.timeout(config.stop_timeout) do
61
- sleep(1) until config.controller.stop
62
- end
63
-
64
- puts "Stopped search daemon (pid #{pid})."
65
- end
7
+ desc 'Generate the Sphinx configuration file'
8
+ task :configure => :environment do
9
+ interface.configure
66
10
  end
67
11
 
68
- desc "Restart Sphinx"
69
- task :restart => [:app_env, :stop, :start]
70
-
71
- desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
72
- task :configure => :app_env do
73
- config = ThinkingSphinx::Configuration.instance
74
- puts "Generating Configuration to #{config.config_file}"
75
- config.build
12
+ desc 'Generate the Sphinx configuration file and process all indices'
13
+ task :index => :environment do
14
+ interface.index(ENV['INDEX_ONLY'] != 'true')
76
15
  end
77
16
 
78
- desc "Index data for Sphinx using Thinking Sphinx's settings"
79
- task :index => :app_env do
80
- config = ThinkingSphinx::Configuration.instance
81
- unless ENV["INDEX_ONLY"] == "true"
82
- puts "Generating Configuration to #{config.config_file}"
83
- config.build
84
- end
17
+ desc 'Stop Sphinx, index and then restart Sphinx'
18
+ task :rebuild => [:stop, :index, :start]
19
+ desc 'Restart the Sphinx daemon'
20
+ task :restart => [:stop, :start]
85
21
 
86
- FileUtils.mkdir_p config.searchd_file_path
87
- ThinkingSphinx.before_index_hooks.each { |hook| hook.call }
88
- config.controller.index :verbose => true
22
+ desc 'Start the Sphinx daemon'
23
+ task :start => :environment do
24
+ interface.start
89
25
  end
90
26
 
91
- desc "Reindex Sphinx without regenerating the configuration file"
92
- task :reindex => :app_env do
93
- config = ThinkingSphinx::Configuration.instance
94
- FileUtils.mkdir_p config.searchd_file_path
95
- output = config.controller.index
96
- puts output
97
- config.touch_reindex_file(output)
27
+ desc 'Stop the Sphinx daemon'
28
+ task :stop => :environment do
29
+ interface.stop
98
30
  end
99
31
 
100
- desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
101
- task :rebuild => :app_env do
102
- Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
103
- Rake::Task["thinking_sphinx:index"].invoke
104
- Rake::Task["thinking_sphinx:start"].invoke
32
+ def interface
33
+ @interface ||= ThinkingSphinx::RakeInterface.new
105
34
  end
106
35
  end
107
-
108
- namespace :ts do
109
- desc "Output the current Thinking Sphinx version"
110
- task :version => "thinking_sphinx:version"
111
- desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
112
- task :run => "thinking_sphinx:running_start"
113
- desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
114
- task :start => "thinking_sphinx:start"
115
- desc "Stop Sphinx using Thinking Sphinx's settings"
116
- task :stop => "thinking_sphinx:stop"
117
- desc "Index data for Sphinx using Thinking Sphinx's settings"
118
- task :in => "thinking_sphinx:index"
119
- task :index => "thinking_sphinx:index"
120
- desc "Reindex Sphinx without regenerating the configuration file"
121
- task :reindex => "thinking_sphinx:reindex"
122
- desc "Restart Sphinx"
123
- task :restart => "thinking_sphinx:restart"
124
- desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
125
- task :conf => "thinking_sphinx:configure"
126
- desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
127
- task :config => "thinking_sphinx:configure"
128
- desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
129
- task :rebuild => "thinking_sphinx:rebuild"
130
- end
131
-
132
- def sphinx_pid
133
- ThinkingSphinx.sphinx_pid
134
- end
135
-
136
- def sphinx_running?
137
- ThinkingSphinx.sphinx_running?
138
- end
@@ -1,31 +1,31 @@
1
1
  class ThinkingSphinx::Test
2
2
  def self.init(suppress_delta_output = true)
3
- set_flags suppress_delta_output
4
- create_indexes_folder
3
+ FileUtils.mkdir_p config.indices_location
4
+ config.settings['quiet_deltas'] = true
5
5
  end
6
-
6
+
7
7
  def self.start
8
8
  config.build
9
9
  config.controller.index
10
10
  config.controller.start
11
11
  end
12
-
12
+
13
13
  def self.start_with_autostop
14
14
  autostop
15
15
  start
16
16
  end
17
-
17
+
18
18
  def self.stop
19
19
  config.controller.stop
20
20
  sleep(0.5) # Ensure Sphinx has shut down completely
21
21
  end
22
-
22
+
23
23
  def self.autostop
24
24
  Kernel.at_exit do
25
25
  ThinkingSphinx::Test.stop
26
26
  end
27
27
  end
28
-
28
+
29
29
  def self.run(&block)
30
30
  begin
31
31
  start
@@ -34,22 +34,12 @@ class ThinkingSphinx::Test
34
34
  stop
35
35
  end
36
36
  end
37
-
37
+
38
38
  def self.config
39
39
  @config ||= ::ThinkingSphinx::Configuration.instance
40
40
  end
41
-
41
+
42
42
  def self.index(*indexes)
43
43
  config.controller.index *indexes
44
44
  end
45
-
46
- def self.set_flags(suppress_delta_output)
47
- ::ThinkingSphinx.deltas_enabled = true
48
- ::ThinkingSphinx.updates_enabled = true
49
- ::ThinkingSphinx.suppress_delta_output = suppress_delta_output
50
- end
51
-
52
- def self.create_indexes_folder
53
- FileUtils.mkdir_p config.searchd_file_path
54
- end
55
45
  end
@@ -0,0 +1,58 @@
1
+ # LOADING ALL CLASSES is invoked by:
2
+ # - call define_index
3
+ # - loading any model with an index definition
4
+ # - because need to add to list of which models have indices.
5
+ # - sphinx document id for an instance is requested
6
+ # - updating attributes
7
+ # - toggling as deleted
8
+ # - when generating configuration
9
+ # - need to build full configuration file.
10
+ # - when loading models_by_crc
11
+ # - searches and facet searches pre Sphinx 2
12
+ # - facet search
13
+ # - search
14
+ #
15
+ # WHY?
16
+ # - need to know which classes are searchable
17
+ # - need to track number of indices (multiplier) - STI matters here
18
+ # - are a subclass and superclass STI pair both indexed? One offset for both.
19
+ # - need to track position of current model within all indexed models (offset)
20
+ # - need to generate configuration
21
+ # - need to know subclasses available to search on.
22
+ #
23
+ # SO:
24
+ # - load all indices *and* related models when needing document id
25
+ # - load all indices *and* related models when generating configuration
26
+ # - maybe can avoid loading all indices and/or related models when searching?
27
+ # - would need to track ancestor models - harder when no multi-string
28
+ # attributes - for filtering on classes. Can we be smart about this and
29
+ # only force a full model load if absolutely necessary? And/or forced by
30
+ # a flag so developers need to request it?
31
+
32
+
33
+
34
+ # Use symbols - avoid loading classes until we need to.
35
+ ThinkingSphinx.define_index_for :article do
36
+ indexes subject, content
37
+ indexes user.name, :as => :user_name
38
+
39
+ has user_id
40
+ end
41
+
42
+ # Or better - let's not add everything to the root of TS module, and make it
43
+ # clear of the index driver.
44
+ ThinkingSphinx::Index.define :article, :with => :active_record do
45
+ indexes subject, content
46
+ indexes user.name, :as => :user_name
47
+
48
+ has user_id
49
+ end
50
+
51
+ # Built-in index driver support could be auto-mapped to methods:
52
+ ThinkingSphinx::Index.define_with_active_record, :article
53
+
54
+ ThinkingSphinx::Index.define_with_realtime :article do
55
+ indexes :subject, :content, :user_name
56
+
57
+ has user_id => :integer
58
+ end