friendlyfashion-thinking-sphinx 2.0.13

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 (175) hide show
  1. data/HISTORY +244 -0
  2. data/LICENCE +20 -0
  3. data/README.textile +235 -0
  4. data/features/abstract_inheritance.feature +10 -0
  5. data/features/alternate_primary_key.feature +27 -0
  6. data/features/attribute_transformation.feature +22 -0
  7. data/features/attribute_updates.feature +77 -0
  8. data/features/deleting_instances.feature +67 -0
  9. data/features/direct_attributes.feature +11 -0
  10. data/features/excerpts.feature +21 -0
  11. data/features/extensible_delta_indexing.feature +9 -0
  12. data/features/facets.feature +88 -0
  13. data/features/facets_across_model.feature +29 -0
  14. data/features/field_sorting.feature +18 -0
  15. data/features/handling_edits.feature +94 -0
  16. data/features/retry_stale_indexes.feature +24 -0
  17. data/features/searching_across_models.feature +20 -0
  18. data/features/searching_by_index.feature +40 -0
  19. data/features/searching_by_model.feature +175 -0
  20. data/features/searching_with_find_arguments.feature +56 -0
  21. data/features/sphinx_detection.feature +25 -0
  22. data/features/sphinx_scopes.feature +68 -0
  23. data/features/step_definitions/alpha_steps.rb +16 -0
  24. data/features/step_definitions/beta_steps.rb +7 -0
  25. data/features/step_definitions/common_steps.rb +201 -0
  26. data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
  27. data/features/step_definitions/facet_steps.rb +96 -0
  28. data/features/step_definitions/find_arguments_steps.rb +36 -0
  29. data/features/step_definitions/gamma_steps.rb +15 -0
  30. data/features/step_definitions/scope_steps.rb +19 -0
  31. data/features/step_definitions/search_steps.rb +94 -0
  32. data/features/step_definitions/sphinx_steps.rb +35 -0
  33. data/features/sti_searching.feature +19 -0
  34. data/features/support/env.rb +27 -0
  35. data/features/support/lib/generic_delta_handler.rb +8 -0
  36. data/features/thinking_sphinx/database.example.yml +3 -0
  37. data/features/thinking_sphinx/db/.gitignore +1 -0
  38. data/features/thinking_sphinx/db/fixtures/alphas.rb +8 -0
  39. data/features/thinking_sphinx/db/fixtures/authors.rb +1 -0
  40. data/features/thinking_sphinx/db/fixtures/betas.rb +11 -0
  41. data/features/thinking_sphinx/db/fixtures/boxes.rb +9 -0
  42. data/features/thinking_sphinx/db/fixtures/categories.rb +1 -0
  43. data/features/thinking_sphinx/db/fixtures/cats.rb +3 -0
  44. data/features/thinking_sphinx/db/fixtures/comments.rb +24 -0
  45. data/features/thinking_sphinx/db/fixtures/developers.rb +31 -0
  46. data/features/thinking_sphinx/db/fixtures/dogs.rb +3 -0
  47. data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +10 -0
  48. data/features/thinking_sphinx/db/fixtures/foxes.rb +3 -0
  49. data/features/thinking_sphinx/db/fixtures/gammas.rb +10 -0
  50. data/features/thinking_sphinx/db/fixtures/music.rb +4 -0
  51. data/features/thinking_sphinx/db/fixtures/people.rb +1001 -0
  52. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +1 -0
  53. data/features/thinking_sphinx/db/fixtures/posts.rb +10 -0
  54. data/features/thinking_sphinx/db/fixtures/robots.rb +8 -0
  55. data/features/thinking_sphinx/db/fixtures/tags.rb +27 -0
  56. data/features/thinking_sphinx/db/migrations/create_alphas.rb +8 -0
  57. data/features/thinking_sphinx/db/migrations/create_animals.rb +5 -0
  58. data/features/thinking_sphinx/db/migrations/create_authors.rb +3 -0
  59. data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +6 -0
  60. data/features/thinking_sphinx/db/migrations/create_betas.rb +5 -0
  61. data/features/thinking_sphinx/db/migrations/create_boxes.rb +5 -0
  62. data/features/thinking_sphinx/db/migrations/create_categories.rb +3 -0
  63. data/features/thinking_sphinx/db/migrations/create_comments.rb +10 -0
  64. data/features/thinking_sphinx/db/migrations/create_developers.rb +7 -0
  65. data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +5 -0
  66. data/features/thinking_sphinx/db/migrations/create_gammas.rb +3 -0
  67. data/features/thinking_sphinx/db/migrations/create_genres.rb +3 -0
  68. data/features/thinking_sphinx/db/migrations/create_music.rb +6 -0
  69. data/features/thinking_sphinx/db/migrations/create_people.rb +13 -0
  70. data/features/thinking_sphinx/db/migrations/create_posts.rb +6 -0
  71. data/features/thinking_sphinx/db/migrations/create_robots.rb +4 -0
  72. data/features/thinking_sphinx/db/migrations/create_taggings.rb +5 -0
  73. data/features/thinking_sphinx/db/migrations/create_tags.rb +4 -0
  74. data/features/thinking_sphinx/models/alpha.rb +23 -0
  75. data/features/thinking_sphinx/models/andrew.rb +17 -0
  76. data/features/thinking_sphinx/models/animal.rb +5 -0
  77. data/features/thinking_sphinx/models/author.rb +3 -0
  78. data/features/thinking_sphinx/models/beta.rb +13 -0
  79. data/features/thinking_sphinx/models/box.rb +8 -0
  80. data/features/thinking_sphinx/models/cat.rb +3 -0
  81. data/features/thinking_sphinx/models/category.rb +4 -0
  82. data/features/thinking_sphinx/models/comment.rb +10 -0
  83. data/features/thinking_sphinx/models/developer.rb +21 -0
  84. data/features/thinking_sphinx/models/dog.rb +3 -0
  85. data/features/thinking_sphinx/models/extensible_beta.rb +9 -0
  86. data/features/thinking_sphinx/models/fox.rb +5 -0
  87. data/features/thinking_sphinx/models/gamma.rb +5 -0
  88. data/features/thinking_sphinx/models/genre.rb +3 -0
  89. data/features/thinking_sphinx/models/medium.rb +5 -0
  90. data/features/thinking_sphinx/models/music.rb +10 -0
  91. data/features/thinking_sphinx/models/person.rb +24 -0
  92. data/features/thinking_sphinx/models/post.rb +22 -0
  93. data/features/thinking_sphinx/models/robot.rb +12 -0
  94. data/features/thinking_sphinx/models/tag.rb +3 -0
  95. data/features/thinking_sphinx/models/tagging.rb +4 -0
  96. data/lib/cucumber/thinking_sphinx/external_world.rb +12 -0
  97. data/lib/cucumber/thinking_sphinx/internal_world.rb +137 -0
  98. data/lib/cucumber/thinking_sphinx/sql_logger.rb +28 -0
  99. data/lib/thinking-sphinx.rb +1 -0
  100. data/lib/thinking_sphinx/action_controller.rb +31 -0
  101. data/lib/thinking_sphinx/active_record/attribute_updates.rb +53 -0
  102. data/lib/thinking_sphinx/active_record/collection_proxy.rb +47 -0
  103. data/lib/thinking_sphinx/active_record/collection_proxy_with_scopes.rb +27 -0
  104. data/lib/thinking_sphinx/active_record/delta.rb +67 -0
  105. data/lib/thinking_sphinx/active_record/has_many_association.rb +44 -0
  106. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +21 -0
  107. data/lib/thinking_sphinx/active_record/log_subscriber.rb +61 -0
  108. data/lib/thinking_sphinx/active_record/scopes.rb +110 -0
  109. data/lib/thinking_sphinx/active_record.rb +386 -0
  110. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +87 -0
  111. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +62 -0
  112. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +188 -0
  113. data/lib/thinking_sphinx/association.rb +230 -0
  114. data/lib/thinking_sphinx/attribute.rb +405 -0
  115. data/lib/thinking_sphinx/auto_version.rb +40 -0
  116. data/lib/thinking_sphinx/bundled_search.rb +44 -0
  117. data/lib/thinking_sphinx/class_facet.rb +20 -0
  118. data/lib/thinking_sphinx/configuration.rb +375 -0
  119. data/lib/thinking_sphinx/context.rb +76 -0
  120. data/lib/thinking_sphinx/core/string.rb +15 -0
  121. data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
  122. data/lib/thinking_sphinx/deltas.rb +28 -0
  123. data/lib/thinking_sphinx/deploy/capistrano.rb +99 -0
  124. data/lib/thinking_sphinx/excerpter.rb +23 -0
  125. data/lib/thinking_sphinx/facet.rb +135 -0
  126. data/lib/thinking_sphinx/facet_search.rb +170 -0
  127. data/lib/thinking_sphinx/field.rb +98 -0
  128. data/lib/thinking_sphinx/index/builder.rb +315 -0
  129. data/lib/thinking_sphinx/index/faux_column.rb +118 -0
  130. data/lib/thinking_sphinx/index.rb +159 -0
  131. data/lib/thinking_sphinx/join.rb +37 -0
  132. data/lib/thinking_sphinx/property.rb +187 -0
  133. data/lib/thinking_sphinx/railtie.rb +43 -0
  134. data/lib/thinking_sphinx/search.rb +1061 -0
  135. data/lib/thinking_sphinx/search_methods.rb +439 -0
  136. data/lib/thinking_sphinx/sinatra.rb +7 -0
  137. data/lib/thinking_sphinx/source/internal_properties.rb +51 -0
  138. data/lib/thinking_sphinx/source/sql.rb +174 -0
  139. data/lib/thinking_sphinx/source.rb +194 -0
  140. data/lib/thinking_sphinx/tasks.rb +142 -0
  141. data/lib/thinking_sphinx/test.rb +55 -0
  142. data/lib/thinking_sphinx/version.rb +3 -0
  143. data/lib/thinking_sphinx.rb +297 -0
  144. data/spec/fixtures/data.sql +32 -0
  145. data/spec/fixtures/database.yml.default +3 -0
  146. data/spec/fixtures/models.rb +164 -0
  147. data/spec/fixtures/structure.sql +146 -0
  148. data/spec/spec_helper.rb +61 -0
  149. data/spec/sphinx_helper.rb +60 -0
  150. data/spec/support/rails.rb +25 -0
  151. data/spec/thinking_sphinx/active_record/delta_spec.rb +122 -0
  152. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +173 -0
  153. data/spec/thinking_sphinx/active_record/scopes_spec.rb +176 -0
  154. data/spec/thinking_sphinx/active_record_spec.rb +573 -0
  155. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +145 -0
  156. data/spec/thinking_sphinx/association_spec.rb +250 -0
  157. data/spec/thinking_sphinx/attribute_spec.rb +552 -0
  158. data/spec/thinking_sphinx/auto_version_spec.rb +103 -0
  159. data/spec/thinking_sphinx/configuration_spec.rb +326 -0
  160. data/spec/thinking_sphinx/context_spec.rb +126 -0
  161. data/spec/thinking_sphinx/core/array_spec.rb +9 -0
  162. data/spec/thinking_sphinx/core/string_spec.rb +9 -0
  163. data/spec/thinking_sphinx/excerpter_spec.rb +49 -0
  164. data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
  165. data/spec/thinking_sphinx/facet_spec.rb +359 -0
  166. data/spec/thinking_sphinx/field_spec.rb +127 -0
  167. data/spec/thinking_sphinx/index/builder_spec.rb +532 -0
  168. data/spec/thinking_sphinx/index/faux_column_spec.rb +36 -0
  169. data/spec/thinking_sphinx/index_spec.rb +189 -0
  170. data/spec/thinking_sphinx/search_methods_spec.rb +156 -0
  171. data/spec/thinking_sphinx/search_spec.rb +1455 -0
  172. data/spec/thinking_sphinx/source_spec.rb +267 -0
  173. data/spec/thinking_sphinx/test_spec.rb +20 -0
  174. data/spec/thinking_sphinx_spec.rb +204 -0
  175. metadata +524 -0
@@ -0,0 +1 @@
1
+ foo bar baz
@@ -0,0 +1,10 @@
1
+ post = Post.create(
2
+ :subject => "Hello World",
3
+ :content => "Um Text",
4
+ :id => 1,
5
+ :category_id => 1,
6
+ :keywords_file => (File.dirname(__FILE__) + '/post_keywords.txt')
7
+ )
8
+
9
+ post.authors << Author.find(:first)
10
+ post.save
@@ -0,0 +1,8 @@
1
+ {
2
+ 'F0001' => 'Fritz',
3
+ 'S0001' => 'Sizzle',
4
+ 'S0002' => 'Sizzle Jr.',
5
+ 'E0001' => 'Expendable'
6
+ }.each do |internal_id, name|
7
+ Robot.connection.execute "INSERT INTO robots (name, internal_id) VALUES ('#{name}', '#{internal_id}')"
8
+ end
@@ -0,0 +1,27 @@
1
+ post = Post.find(1)
2
+
3
+ [
4
+ 'Nunc in neque. Integer sed odio ac quam pellentesque suscipit. Cras posuere posuere est. Suspendisse est.',
5
+ 'In hac habitasse platea dictumst. Etiam eleifend est ac diam. Ut ac felis sit amet mi bibendum varius.',
6
+ 'Nullam sollicitudin tellus at ipsum. Duis mi eros, blandit sed, condimentum non, mattis vel, orci.',
7
+ 'Praesent auctor mollis leo. Nulla facilisi. Pellentesque habitant morbi tristique senectus et netus et',
8
+ 'malesuada fames ac turpis egestas. Donec non odio. Maecenas varius elit ut ante. Phasellus egestas, quam',
9
+ 'a congue euismod, diam urna gravida risus, at euismod lectus diam id sem. Vestibulum sed dolor et massa',
10
+ 'porta placerat. Etiam eget risus. Sed ornare. Vivamus in sapien. Maecenas non enim nec metus posuere',
11
+ 'vehicula. Donec rhoncus mauris at metus. Curabitur volutpat massa a metus. Aliquam ornare, neque ut',
12
+ 'tristique convallis, libero orci eleifend nibh, ac porta leo felis sed orci. Lorem ipsum dolor sit amet,',
13
+ 'Waffles' # This one is important, whereas the others are just padding
14
+ ].each do |text|
15
+ Tagging.create :taggable => post, :tag => Tag.create(:text => text)
16
+ end
17
+
18
+ Developer.find(:all).each do |developer|
19
+ [:country, :city, :state].each do |column|
20
+ Tagging.create(
21
+ :taggable => developer,
22
+ :tag => Tag.find_or_create_by_text(developer.send(column))
23
+ )
24
+ end
25
+ end
26
+
27
+ Tagging.create(:taggable => Developer.find(:all).last)
@@ -0,0 +1,8 @@
1
+ ActiveRecord::Base.connection.create_table :alphas, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :value, :integer, :null => false
4
+ t.column :active, :boolean, :null => false, :default => true
5
+ t.column :cost, :decimal, :precision => 10, :scale => 6
6
+ t.column :created_on, :date
7
+ t.column :created_at, :timestamp
8
+ end
@@ -0,0 +1,5 @@
1
+ ActiveRecord::Base.connection.create_table :animals, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :type, :string
4
+ t.column :delta, :boolean, :null => false, :default => false
5
+ end
@@ -0,0 +1,3 @@
1
+ ActiveRecord::Base.connection.create_table :authors, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ end
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Base.connection.create_table(
2
+ :authors_posts, :force => true, :id => false
3
+ ) do |t|
4
+ t.column :author_id, :integer, :null => false
5
+ t.column :post_id, :integer, :null => false
6
+ end
@@ -0,0 +1,5 @@
1
+ ActiveRecord::Base.connection.create_table :betas, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :value, :integer, :null => false
4
+ t.column :delta, :boolean, :null => false, :default => false
5
+ end
@@ -0,0 +1,5 @@
1
+ ActiveRecord::Base.connection.create_table :boxes, :force => true do |t|
2
+ t.column :width, :integer, :null => false
3
+ t.column :length, :integer, :null => false
4
+ t.column :depth, :integer
5
+ end
@@ -0,0 +1,3 @@
1
+ ActiveRecord::Base.connection.create_table :categories, :force => true do |t|
2
+ t.column :name, :string
3
+ end
@@ -0,0 +1,10 @@
1
+ ActiveRecord::Base.connection.create_table :comments, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :email, :string
4
+ t.column :url, :string
5
+ t.column :content, :text
6
+ t.column :post_id, :integer, :null => false
7
+ t.column :category_id, :integer, :null => false
8
+ t.column :created_at, :datetime
9
+ t.column :updated_at, :datetime
10
+ end
@@ -0,0 +1,7 @@
1
+ ActiveRecord::Base.connection.create_table :developers, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :city, :string
4
+ t.column :state, :string
5
+ t.column :country, :string
6
+ t.column :age, :integer
7
+ end
@@ -0,0 +1,5 @@
1
+ ActiveRecord::Base.connection.create_table :extensible_betas, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :delta, :boolean, :null => false, :default => false
4
+ t.column :changed_by_generic, :boolean, :null => false, :default => false
5
+ end
@@ -0,0 +1,3 @@
1
+ ActiveRecord::Base.connection.create_table :gammas, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ end
@@ -0,0 +1,3 @@
1
+ ActiveRecord::Base.connection.create_table :genres, :force => true do |t|
2
+ t.column :name, :string
3
+ end
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Base.connection.create_table :music, :force => true do |t|
2
+ t.column :artist, :string
3
+ t.column :album, :string
4
+ t.column :track, :string
5
+ t.column :genre_id, :integer
6
+ end
@@ -0,0 +1,13 @@
1
+ ActiveRecord::Base.connection.create_table :people, :force => true do |t|
2
+ t.column :first_name, :string
3
+ t.column :middle_initial, :string
4
+ t.column :last_name, :string
5
+ t.column :gender, :string
6
+ t.column :street_address, :string
7
+ t.column :city, :string
8
+ t.column :state, :string
9
+ t.column :postcode, :string
10
+ t.column :email, :string
11
+ t.column :birthday, :datetime
12
+ t.column :delta, :boolean, :null => false, :default => false
13
+ end
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Base.connection.create_table :posts, :force => true do |t|
2
+ t.column :subject, :string, :null => false
3
+ t.column :content, :text
4
+ t.column :category_id, :integer, :null => false
5
+ t.column :keywords_file, :string
6
+ end
@@ -0,0 +1,4 @@
1
+ ActiveRecord::Base.connection.create_table :robots, :primary_key => :alternate_primary_key, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :internal_id, :string, :null => false
4
+ end
@@ -0,0 +1,5 @@
1
+ ActiveRecord::Base.connection.create_table :taggings, :force => true do |t|
2
+ t.column :tag_id, :integer
3
+ t.column :taggable_id, :integer, :null => false
4
+ t.column :taggable_type, :string, :null => false
5
+ end
@@ -0,0 +1,4 @@
1
+ ActiveRecord::Base.connection.create_table :tags, :force => true do |t|
2
+ # t.column :post_id, :integer, :null => false
3
+ t.column :text, :text, :null => true
4
+ end
@@ -0,0 +1,23 @@
1
+ class Alpha < ActiveRecord::Base
2
+ define_index do
3
+ indexes :name, :sortable => true
4
+
5
+ has value, created_at, created_on
6
+ has cost, :facet => true
7
+ has active
8
+
9
+ set_property :field_weights => {"name" => 10}
10
+ end
11
+
12
+ define_index 'alternative' do
13
+ indexes :name, :as => :alternative_name, :sortable => true
14
+
15
+ has value, created_at, created_on
16
+ has cost, :facet => true
17
+ has active
18
+
19
+ set_property :field_weights => {'alternative_name' => 10}
20
+
21
+ where "value > 3"
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ require "#{File.dirname(__FILE__)}/person"
2
+
3
+ class Andrew < ActiveRecord::Base
4
+ set_table_name 'people'
5
+
6
+ define_index do
7
+ indexes first_name, last_name, street_address
8
+ end
9
+
10
+ sphinx_scope(:locked_first_name) {
11
+ {:conditions => {:first_name => 'Andrew'}}
12
+ }
13
+ sphinx_scope(:locked_last_name) {
14
+ {:conditions => {:last_name => 'Byrne'}}
15
+ }
16
+ default_sphinx_scope :locked_first_name
17
+ end
@@ -0,0 +1,5 @@
1
+ class Animal < ActiveRecord::Base
2
+ define_index do
3
+ indexes name, :sortable => true
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ class Author < ActiveRecord::Base
2
+ #
3
+ end
@@ -0,0 +1,13 @@
1
+ class Beta < ActiveRecord::Base
2
+ define_index do
3
+ indexes :name, :sortable => true, :facet => true
4
+ has value
5
+ end
6
+
7
+ define_index 'secondary_beta' do
8
+ indexes :name, :sortable => true, :facet => true
9
+ has value
10
+
11
+ set_property :delta => true
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ class Box < ActiveRecord::Base
2
+ define_index do
3
+ indexes width, :as => :width_field
4
+
5
+ has width, length, depth
6
+ has [width, length, depth], :as => :dimensions
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ class Cat < Animal
2
+ #
3
+ end
@@ -0,0 +1,4 @@
1
+ class Category < ActiveRecord::Base
2
+ has_many :posts
3
+ has_many :comments
4
+ end
@@ -0,0 +1,10 @@
1
+ class Comment < ActiveRecord::Base
2
+ define_index do
3
+ indexes :content
4
+
5
+ has category.name, :facet => true, :as => :category_name, :type => :string
6
+ end
7
+
8
+ belongs_to :post
9
+ belongs_to :category
10
+ end
@@ -0,0 +1,21 @@
1
+ require "#{File.dirname(__FILE__)}/tag"
2
+ require "#{File.dirname(__FILE__)}/tagging"
3
+
4
+ class Developer < ActiveRecord::Base
5
+ has_many :taggings, :as => :taggable
6
+ has_many :tags, :through => :taggings
7
+
8
+ define_index do
9
+ indexes country, :facet => true
10
+ indexes state, :facet => true
11
+ indexes tags.text, :as => :tags, :facet => true
12
+
13
+ has age, :facet => true
14
+ has tags(:id), :as => :tag_ids, :facet => true
15
+ has state, :as => :state_wordcount, :type => :wordcount
16
+
17
+ facet "LOWER(city)", :as => :city, :type => :string, :value => :city
18
+
19
+ group_by 'city'
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ class Dog < Animal
2
+ #
3
+ end
@@ -0,0 +1,9 @@
1
+ require "#{Dir.pwd}/features/support/lib/generic_delta_handler"
2
+
3
+ class ExtensibleBeta < ActiveRecord::Base
4
+ define_index do
5
+ indexes :name, :sortable => true
6
+
7
+ set_property :delta => "GenericDeltaHandler"
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ class Fox < Animal
2
+ define_index do
3
+ indexes :name
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Gamma < ActiveRecord::Base
2
+ define_index do
3
+ indexes :name, :sortable => true
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ class Genre < ActiveRecord::Base
2
+ #
3
+ end
@@ -0,0 +1,5 @@
1
+ class Medium < ActiveRecord::Base
2
+ self.abstract_class = true
3
+
4
+ belongs_to :genre
5
+ end
@@ -0,0 +1,10 @@
1
+ class Music < Medium
2
+ set_table_name 'music'
3
+
4
+ define_index do
5
+ indexes artist, :with => :attribute
6
+ indexes track
7
+ indexes album, :with => :wordcount
8
+ indexes genre(:name), :as => :genre
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ class Person < ActiveRecord::Base
2
+ define_index do
3
+ indexes first_name, :sortable => true
4
+ indexes last_name, :sortable => :insensitive
5
+
6
+ has [first_name, middle_initial, last_name], :as => :name_sort
7
+ has birthday
8
+ has gender, :facet => true
9
+
10
+ set_property :min_infix_len => 1
11
+ set_property :enable_star => true
12
+ end
13
+
14
+ sphinx_scope(:with_first_name) { |name|
15
+ { :conditions => {:first_name => name} }
16
+ }
17
+ sphinx_scope(:with_last_name) { |name|
18
+ { :conditions => {:last_name => name} }
19
+ }
20
+ sphinx_scope(:with_id) { |id|
21
+ { :with => {:sphinx_internal_id => id} }
22
+ }
23
+ sphinx_scope(:ids_only) { {:ids_only => true} }
24
+ end
@@ -0,0 +1,22 @@
1
+ class Post < ActiveRecord::Base
2
+ has_many :comments, :dependent => :destroy
3
+ has_many :taggings, :as => :taggable
4
+ has_many :tags, :through => :taggings
5
+ belongs_to :category
6
+ has_and_belongs_to_many :authors
7
+
8
+ define_index do
9
+ indexes subject
10
+ indexes content
11
+ indexes tags.text, :as => :tags
12
+ indexes comments.content, :as => :comments
13
+ indexes authors.name, :as => :authors
14
+ indexes keywords_file, :as => :keywords, :file => true
15
+
16
+ has comments(:id), :as => :comment_ids, :source => :ranged_query,
17
+ :facet => true
18
+ has category.name, :facet => true, :as => :category_name, :type => :string
19
+ has 'COUNT(DISTINCT comments.id)', :as => :comments_count, :type => :integer
20
+ has comments.created_at, :as => :comments_created_at
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ class Robot < ActiveRecord::Base
2
+ set_primary_key :internal_id
3
+ set_sphinx_primary_key :alternate_primary_key
4
+
5
+ define_index do
6
+ indexes :name
7
+ end
8
+
9
+ def id
10
+ internal_id
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ class Tag < ActiveRecord::Base
2
+ belongs_to :post
3
+ end
@@ -0,0 +1,4 @@
1
+ class Tagging < ActiveRecord::Base
2
+ belongs_to :tag
3
+ belongs_to :taggable, :polymorphic => true
4
+ end
@@ -0,0 +1,12 @@
1
+ require 'thinking_sphinx/test'
2
+
3
+ module Cucumber
4
+ module ThinkingSphinx
5
+ class ExternalWorld
6
+ def initialize(suppress_delta_output = true)
7
+ ::ThinkingSphinx::Test.init
8
+ ::ThinkingSphinx::Test.start_with_autostop
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,137 @@
1
+ require 'cucumber/thinking_sphinx/sql_logger'
2
+
3
+ module Cucumber
4
+ module ThinkingSphinx
5
+ class InternalWorld
6
+ attr_accessor :temporary_directory, :migrations_directory,
7
+ :models_directory, :fixtures_directory, :database_file
8
+ attr_accessor :adapter, :database, :username,
9
+ :password, :host
10
+
11
+ def initialize
12
+ pwd = Dir.pwd
13
+ @temporary_directory = "#{pwd}/tmp"
14
+ @migrations_directory = "#{pwd}/features/thinking_sphinx/db/migrations"
15
+ @models_directory = "#{pwd}/features/thinking_sphinx/models"
16
+ @fixtures_directory = "#{pwd}/features/thinking_sphinx/db/fixtures"
17
+ @database_file = "#{pwd}/features/thinking_sphinx/database.yml"
18
+
19
+ @adapter = (ENV['DATABASE'] || 'mysql').gsub /^mysql$/, 'mysql2'
20
+ @database = 'thinking_sphinx'
21
+ @username = ENV['USER']
22
+ @host = 'localhost'
23
+
24
+ if @adapter[/mysql/]
25
+ @username = 'root'
26
+ elsif ENV['TRAVIS']
27
+ @username = 'postgres'
28
+ end
29
+ end
30
+
31
+ def setup
32
+ make_temporary_directory
33
+
34
+ configure_cleanup
35
+ configure_thinking_sphinx
36
+ configure_active_record
37
+
38
+ prepare_data
39
+ setup_sphinx
40
+
41
+ self
42
+ end
43
+
44
+ def configure_database
45
+ ActiveRecord::Base.establish_connection database_settings
46
+ self
47
+ end
48
+
49
+ private
50
+
51
+ def config
52
+ @config ||= ::ThinkingSphinx::Configuration.instance
53
+ end
54
+
55
+ def make_temporary_directory
56
+ FileUtils.mkdir_p temporary_directory
57
+ Dir["#{temporary_directory}/*"].each do |file|
58
+ FileUtils.rm_rf file
59
+ end
60
+ end
61
+
62
+ def configure_thinking_sphinx
63
+ config.config_file = "#{temporary_directory}/sphinx.conf"
64
+ config.searchd_log_file = "#{temporary_directory}/searchd.log"
65
+ config.query_log_file = "#{temporary_directory}/searchd.query.log"
66
+ config.pid_file = "#{temporary_directory}/searchd.pid"
67
+ config.searchd_file_path = "#{temporary_directory}/indexes/"
68
+
69
+ ::ThinkingSphinx.suppress_delta_output = true
70
+ end
71
+
72
+ def configure_cleanup
73
+ Kernel.at_exit do
74
+ ::ThinkingSphinx::Configuration.instance.controller.stop
75
+ sleep(0.5) # Ensure Sphinx has shut down completely
76
+ ::ThinkingSphinx::ActiveRecord::LogSubscriber.logger.close
77
+ ::ActiveRecord::Base.logger.close
78
+ end
79
+ end
80
+
81
+ def yaml_database_settings
82
+ return {} unless File.exist?(@database_file)
83
+
84
+ YAML.load open(@database_file)
85
+ end
86
+
87
+ def database_settings
88
+ {
89
+ 'adapter' => @adapter,
90
+ 'database' => @database,
91
+ 'username' => @username,
92
+ 'password' => @password,
93
+ 'host' => @host
94
+ }.merge yaml_database_settings
95
+ end
96
+
97
+ def configure_active_record
98
+ ::ActiveRecord::Base.logger = Logger.new(
99
+ open("#{temporary_directory}/active_record.log", "a")
100
+ )
101
+
102
+ ::ThinkingSphinx::ActiveRecord::LogSubscriber.logger = Logger.new(
103
+ open("#{temporary_directory}/active_record.log", "a")
104
+ )
105
+
106
+ ActiveRecord::Base.connection.class.send(
107
+ :include, Cucumber::ThinkingSphinx::SqlLogger
108
+ )
109
+ end
110
+
111
+ def prepare_data
112
+ ::ThinkingSphinx.deltas_enabled = false
113
+
114
+ load_files migrations_directory
115
+ load_files models_directory
116
+ load_files fixtures_directory
117
+
118
+ ::ThinkingSphinx.deltas_enabled = true
119
+ end
120
+
121
+ def load_files(path)
122
+ files = Dir["#{path}/*.rb"].sort!
123
+ files.each do |file|
124
+ require file.gsub(/\.rb$/, '')
125
+ end
126
+ end
127
+
128
+ def setup_sphinx
129
+ FileUtils.mkdir_p config.searchd_file_path
130
+
131
+ config.build
132
+ config.controller.index
133
+ config.controller.start
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,28 @@
1
+ module Cucumber
2
+ module ThinkingSphinx
3
+ module SqlLogger
4
+ IGNORED_SQL = [
5
+ /^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/,
6
+ /^SELECT @@ROWCOUNT/, /^SHOW FIELDS/
7
+ ]
8
+
9
+ if ActiveRecord::VERSION::STRING.to_f > 3.0
10
+ def log(sql, name = 'SQL', binds = [])
11
+ $queries_executed ||= []
12
+ $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
13
+ super sql, name, binds
14
+ end
15
+ else
16
+ def self.included(base)
17
+ base.send :alias_method_chain, :execute, :query_record
18
+ end
19
+
20
+ def execute_with_query_record(sql, name = 'SQL', &block)
21
+ $queries_executed ||= []
22
+ $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
23
+ execute_without_query_record(sql, name, &block)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1 @@
1
+ require 'thinking_sphinx'
@@ -0,0 +1,31 @@
1
+ module ThinkingSphinx
2
+ module ActionController
3
+ extend ActiveSupport::Concern
4
+
5
+ protected
6
+
7
+ attr_internal :query_runtime
8
+
9
+ def cleanup_view_runtime
10
+ log_subscriber = ThinkingSphinx::ActiveRecord::LogSubscriber
11
+ query_runtime_pre_render = log_subscriber.reset_runtime
12
+ runtime = super
13
+ query_runtime_post_render = log_subscriber.reset_runtime
14
+ self.query_runtime = query_runtime_pre_render + query_runtime_post_render
15
+ runtime - query_runtime_post_render
16
+ end
17
+
18
+ def append_info_to_payload(payload)
19
+ super
20
+ payload[:query_runtime] = query_runtime
21
+ end
22
+
23
+ module ClassMethods
24
+ def log_process_action(payload)
25
+ messages, query_runtime = super, payload[:query_runtime]
26
+ messages << ("Sphinx: %.1fms" % query_runtime.to_f) if query_runtime
27
+ messages
28
+ end
29
+ end
30
+ end
31
+ end