skalee-thinking-sphinx 1.3.14.1

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 (199) hide show
  1. data/LICENCE +20 -0
  2. data/README.textile +201 -0
  3. data/Rakefile +3 -0
  4. data/VERSION +1 -0
  5. data/contribute.rb +385 -0
  6. data/cucumber.yml +1 -0
  7. data/features/abstract_inheritance.feature +10 -0
  8. data/features/alternate_primary_key.feature +27 -0
  9. data/features/attribute_transformation.feature +22 -0
  10. data/features/attribute_updates.feature +51 -0
  11. data/features/deleting_instances.feature +67 -0
  12. data/features/direct_attributes.feature +11 -0
  13. data/features/excerpts.feature +13 -0
  14. data/features/extensible_delta_indexing.feature +9 -0
  15. data/features/facets.feature +82 -0
  16. data/features/facets_across_model.feature +29 -0
  17. data/features/handling_edits.feature +92 -0
  18. data/features/retry_stale_indexes.feature +24 -0
  19. data/features/searching_across_models.feature +20 -0
  20. data/features/searching_by_index.feature +40 -0
  21. data/features/searching_by_model.feature +175 -0
  22. data/features/searching_with_find_arguments.feature +56 -0
  23. data/features/sphinx_detection.feature +25 -0
  24. data/features/sphinx_scopes.feature +42 -0
  25. data/features/step_definitions/alpha_steps.rb +16 -0
  26. data/features/step_definitions/beta_steps.rb +7 -0
  27. data/features/step_definitions/common_steps.rb +188 -0
  28. data/features/step_definitions/extensible_delta_indexing_steps.rb +7 -0
  29. data/features/step_definitions/facet_steps.rb +96 -0
  30. data/features/step_definitions/find_arguments_steps.rb +36 -0
  31. data/features/step_definitions/gamma_steps.rb +15 -0
  32. data/features/step_definitions/scope_steps.rb +15 -0
  33. data/features/step_definitions/search_steps.rb +89 -0
  34. data/features/step_definitions/sphinx_steps.rb +35 -0
  35. data/features/sti_searching.feature +19 -0
  36. data/features/support/database.example.yml +3 -0
  37. data/features/support/db/.gitignore +1 -0
  38. data/features/support/db/fixtures/alphas.rb +10 -0
  39. data/features/support/db/fixtures/authors.rb +1 -0
  40. data/features/support/db/fixtures/betas.rb +10 -0
  41. data/features/support/db/fixtures/boxes.rb +9 -0
  42. data/features/support/db/fixtures/categories.rb +1 -0
  43. data/features/support/db/fixtures/cats.rb +3 -0
  44. data/features/support/db/fixtures/comments.rb +24 -0
  45. data/features/support/db/fixtures/developers.rb +29 -0
  46. data/features/support/db/fixtures/dogs.rb +3 -0
  47. data/features/support/db/fixtures/extensible_betas.rb +10 -0
  48. data/features/support/db/fixtures/foxes.rb +3 -0
  49. data/features/support/db/fixtures/gammas.rb +10 -0
  50. data/features/support/db/fixtures/music.rb +4 -0
  51. data/features/support/db/fixtures/people.rb +1001 -0
  52. data/features/support/db/fixtures/posts.rb +6 -0
  53. data/features/support/db/fixtures/robots.rb +14 -0
  54. data/features/support/db/fixtures/tags.rb +27 -0
  55. data/features/support/db/migrations/create_alphas.rb +8 -0
  56. data/features/support/db/migrations/create_animals.rb +5 -0
  57. data/features/support/db/migrations/create_authors.rb +3 -0
  58. data/features/support/db/migrations/create_authors_posts.rb +6 -0
  59. data/features/support/db/migrations/create_betas.rb +5 -0
  60. data/features/support/db/migrations/create_boxes.rb +5 -0
  61. data/features/support/db/migrations/create_categories.rb +3 -0
  62. data/features/support/db/migrations/create_comments.rb +10 -0
  63. data/features/support/db/migrations/create_developers.rb +9 -0
  64. data/features/support/db/migrations/create_extensible_betas.rb +5 -0
  65. data/features/support/db/migrations/create_gammas.rb +3 -0
  66. data/features/support/db/migrations/create_genres.rb +3 -0
  67. data/features/support/db/migrations/create_music.rb +6 -0
  68. data/features/support/db/migrations/create_people.rb +13 -0
  69. data/features/support/db/migrations/create_posts.rb +5 -0
  70. data/features/support/db/migrations/create_robots.rb +4 -0
  71. data/features/support/db/migrations/create_taggings.rb +5 -0
  72. data/features/support/db/migrations/create_tags.rb +4 -0
  73. data/features/support/env.rb +21 -0
  74. data/features/support/lib/generic_delta_handler.rb +8 -0
  75. data/features/support/models/alpha.rb +22 -0
  76. data/features/support/models/animal.rb +5 -0
  77. data/features/support/models/author.rb +3 -0
  78. data/features/support/models/beta.rb +8 -0
  79. data/features/support/models/box.rb +8 -0
  80. data/features/support/models/cat.rb +3 -0
  81. data/features/support/models/category.rb +4 -0
  82. data/features/support/models/comment.rb +10 -0
  83. data/features/support/models/developer.rb +16 -0
  84. data/features/support/models/dog.rb +3 -0
  85. data/features/support/models/extensible_beta.rb +9 -0
  86. data/features/support/models/fox.rb +5 -0
  87. data/features/support/models/gamma.rb +5 -0
  88. data/features/support/models/genre.rb +3 -0
  89. data/features/support/models/medium.rb +5 -0
  90. data/features/support/models/music.rb +8 -0
  91. data/features/support/models/person.rb +23 -0
  92. data/features/support/models/post.rb +21 -0
  93. data/features/support/models/robot.rb +12 -0
  94. data/features/support/models/tag.rb +3 -0
  95. data/features/support/models/tagging.rb +4 -0
  96. data/ginger_scenarios.rb +28 -0
  97. data/init.rb +5 -0
  98. data/install.rb +5 -0
  99. data/lib/cucumber/thinking_sphinx/external_world.rb +8 -0
  100. data/lib/cucumber/thinking_sphinx/internal_world.rb +126 -0
  101. data/lib/cucumber/thinking_sphinx/sql_logger.rb +20 -0
  102. data/lib/thinking_sphinx/active_record/attribute_updates.rb +19 -0
  103. data/lib/thinking_sphinx/active_record/delta.rb +47 -0
  104. data/lib/thinking_sphinx/active_record/has_many_association.rb +29 -0
  105. data/lib/thinking_sphinx/active_record/scopes.rb +75 -0
  106. data/lib/thinking_sphinx/active_record.rb +348 -0
  107. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
  108. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
  109. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +143 -0
  110. data/lib/thinking_sphinx/association.rb +164 -0
  111. data/lib/thinking_sphinx/attribute.rb +362 -0
  112. data/lib/thinking_sphinx/auto_version.rb +22 -0
  113. data/lib/thinking_sphinx/class_facet.rb +15 -0
  114. data/lib/thinking_sphinx/configuration.rb +300 -0
  115. data/lib/thinking_sphinx/context.rb +68 -0
  116. data/lib/thinking_sphinx/core/array.rb +7 -0
  117. data/lib/thinking_sphinx/core/string.rb +15 -0
  118. data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
  119. data/lib/thinking_sphinx/deltas.rb +28 -0
  120. data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
  121. data/lib/thinking_sphinx/excerpter.rb +22 -0
  122. data/lib/thinking_sphinx/facet.rb +125 -0
  123. data/lib/thinking_sphinx/facet_search.rb +136 -0
  124. data/lib/thinking_sphinx/field.rb +82 -0
  125. data/lib/thinking_sphinx/index/builder.rb +296 -0
  126. data/lib/thinking_sphinx/index/faux_column.rb +110 -0
  127. data/lib/thinking_sphinx/index.rb +157 -0
  128. data/lib/thinking_sphinx/property.rb +162 -0
  129. data/lib/thinking_sphinx/rails_additions.rb +150 -0
  130. data/lib/thinking_sphinx/search.rb +769 -0
  131. data/lib/thinking_sphinx/search_methods.rb +439 -0
  132. data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
  133. data/lib/thinking_sphinx/source/sql.rb +130 -0
  134. data/lib/thinking_sphinx/source.rb +153 -0
  135. data/lib/thinking_sphinx/tasks.rb +131 -0
  136. data/lib/thinking_sphinx/test.rb +52 -0
  137. data/lib/thinking_sphinx.rb +225 -0
  138. data/rails/init.rb +16 -0
  139. data/recipes/thinking_sphinx.rb +3 -0
  140. data/spec/fixtures/data.sql +32 -0
  141. data/spec/fixtures/database.yml.default +3 -0
  142. data/spec/fixtures/models.rb +145 -0
  143. data/spec/fixtures/structure.sql +125 -0
  144. data/spec/spec_helper.rb +60 -0
  145. data/spec/sphinx_helper.rb +81 -0
  146. data/spec/thinking_sphinx/active_record/delta_spec.rb +128 -0
  147. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +55 -0
  148. data/spec/thinking_sphinx/active_record/scopes_spec.rb +177 -0
  149. data/spec/thinking_sphinx/active_record_spec.rb +622 -0
  150. data/spec/thinking_sphinx/association_spec.rb +239 -0
  151. data/spec/thinking_sphinx/attribute_spec.rb +570 -0
  152. data/spec/thinking_sphinx/auto_version_spec.rb +39 -0
  153. data/spec/thinking_sphinx/configuration_spec.rb +234 -0
  154. data/spec/thinking_sphinx/context_spec.rb +119 -0
  155. data/spec/thinking_sphinx/core/array_spec.rb +9 -0
  156. data/spec/thinking_sphinx/core/string_spec.rb +9 -0
  157. data/spec/thinking_sphinx/excerpter_spec.rb +57 -0
  158. data/spec/thinking_sphinx/facet_search_spec.rb +176 -0
  159. data/spec/thinking_sphinx/facet_spec.rb +333 -0
  160. data/spec/thinking_sphinx/field_spec.rb +154 -0
  161. data/spec/thinking_sphinx/index/builder_spec.rb +479 -0
  162. data/spec/thinking_sphinx/index/faux_column_spec.rb +30 -0
  163. data/spec/thinking_sphinx/index_spec.rb +183 -0
  164. data/spec/thinking_sphinx/rails_additions_spec.rb +203 -0
  165. data/spec/thinking_sphinx/search_methods_spec.rb +152 -0
  166. data/spec/thinking_sphinx/search_spec.rb +1181 -0
  167. data/spec/thinking_sphinx/source_spec.rb +235 -0
  168. data/spec/thinking_sphinx_spec.rb +204 -0
  169. data/tasks/distribution.rb +41 -0
  170. data/tasks/rails.rake +1 -0
  171. data/tasks/testing.rb +72 -0
  172. data/vendor/after_commit/.gitignore +1 -0
  173. data/vendor/after_commit/lib/after_commit/active_record.rb +122 -0
  174. data/vendor/after_commit/lib/after_commit/connection_adapters.rb +168 -0
  175. data/vendor/after_commit/lib/after_commit/test_bypass.rb +30 -0
  176. data/vendor/after_commit/lib/after_commit.rb +70 -0
  177. data/vendor/riddle/lib/riddle/0.9.8.rb +1 -0
  178. data/vendor/riddle/lib/riddle/0.9.9/client/filter.rb +22 -0
  179. data/vendor/riddle/lib/riddle/0.9.9/client.rb +49 -0
  180. data/vendor/riddle/lib/riddle/0.9.9/configuration/searchd.rb +28 -0
  181. data/vendor/riddle/lib/riddle/0.9.9.rb +7 -0
  182. data/vendor/riddle/lib/riddle/auto_version.rb +11 -0
  183. data/vendor/riddle/lib/riddle/client/filter.rb +62 -0
  184. data/vendor/riddle/lib/riddle/client/message.rb +70 -0
  185. data/vendor/riddle/lib/riddle/client/response.rb +94 -0
  186. data/vendor/riddle/lib/riddle/client.rb +745 -0
  187. data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +49 -0
  188. data/vendor/riddle/lib/riddle/configuration/index.rb +149 -0
  189. data/vendor/riddle/lib/riddle/configuration/indexer.rb +20 -0
  190. data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
  191. data/vendor/riddle/lib/riddle/configuration/searchd.rb +28 -0
  192. data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
  193. data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
  194. data/vendor/riddle/lib/riddle/configuration/sql_source.rb +53 -0
  195. data/vendor/riddle/lib/riddle/configuration/xml_source.rb +29 -0
  196. data/vendor/riddle/lib/riddle/configuration.rb +33 -0
  197. data/vendor/riddle/lib/riddle/controller.rb +78 -0
  198. data/vendor/riddle/lib/riddle.rb +51 -0
  199. metadata +312 -0
@@ -0,0 +1,153 @@
1
+ require 'thinking_sphinx/source/internal_properties'
2
+ require 'thinking_sphinx/source/sql'
3
+
4
+ module ThinkingSphinx
5
+ class Source
6
+ include ThinkingSphinx::Source::InternalProperties
7
+ include ThinkingSphinx::Source::SQL
8
+
9
+ attr_accessor :model, :fields, :attributes, :conditions, :groupings,
10
+ :options
11
+ attr_reader :base, :index, :database_configuration
12
+
13
+ def initialize(index, options = {})
14
+ @index = index
15
+ @model = index.model
16
+ @fields = []
17
+ @attributes = []
18
+ @conditions = []
19
+ @groupings = []
20
+ @options = options
21
+ @associations = {}
22
+ @database_configuration = @model.connection.
23
+ instance_variable_get(:@config).clone
24
+
25
+ @base = ::ActiveRecord::Associations::ClassMethods::JoinDependency.new(
26
+ @model, [], nil
27
+ )
28
+
29
+ unless @model.descends_from_active_record?
30
+ stored_class = @model.store_full_sti_class ? @model.name : @model.name.demodulize
31
+ @conditions << "#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)} = '#{stored_class}'"
32
+ end
33
+
34
+ add_internal_attributes_and_facets
35
+ end
36
+
37
+ def name
38
+ index.name
39
+ end
40
+
41
+ def to_riddle_for_core(offset, position)
42
+ source = Riddle::Configuration::SQLSource.new(
43
+ "#{index.core_name}_#{position}", adapter.sphinx_identifier
44
+ )
45
+
46
+ set_source_database_settings source
47
+ set_source_attributes source, offset
48
+ set_source_settings source
49
+ set_source_sql source, offset
50
+
51
+ source
52
+ end
53
+
54
+ def to_riddle_for_delta(offset, position)
55
+ source = Riddle::Configuration::SQLSource.new(
56
+ "#{index.delta_name}_#{position}", adapter.sphinx_identifier
57
+ )
58
+ source.parent = "#{index.core_name}_#{position}"
59
+
60
+ set_source_database_settings source
61
+ set_source_attributes source, offset, true
62
+ set_source_settings source
63
+ set_source_sql source, offset, true
64
+
65
+ source
66
+ end
67
+
68
+ def delta?
69
+ !@index.delta_object.nil?
70
+ end
71
+
72
+ # Gets the association stack for a specific key.
73
+ #
74
+ def association(key)
75
+ @associations[key] ||= Association.children(@model, key)
76
+ end
77
+
78
+ private
79
+
80
+ def adapter
81
+ @adapter ||= @model.sphinx_database_adapter
82
+ end
83
+
84
+ def set_source_database_settings(source)
85
+ config = @database_configuration
86
+
87
+ source.sql_host = config[:host] || "localhost"
88
+ source.sql_user = config[:username] || config[:user] || 'root'
89
+ source.sql_pass = (config[:password].to_s || "").gsub('#', '\#')
90
+ source.sql_db = config[:database]
91
+ source.sql_port = config[:port]
92
+ source.sql_sock = config[:socket]
93
+ end
94
+
95
+ def set_source_attributes(source, offset, delta = false)
96
+ attributes.each do |attrib|
97
+ source.send(attrib.type_to_config) << attrib.config_value(offset, delta)
98
+ end
99
+ end
100
+
101
+ def set_source_sql(source, offset, delta = false)
102
+ source.sql_query = to_sql(:offset => offset, :delta => delta).gsub(/\n/, ' ')
103
+ source.sql_query_range = to_sql_query_range(:delta => delta)
104
+ source.sql_query_info = to_sql_query_info(offset)
105
+
106
+ source.sql_query_pre += send(!delta ? :sql_query_pre_for_core : :sql_query_pre_for_delta)
107
+
108
+ if @index.local_options[:group_concat_max_len]
109
+ source.sql_query_pre << "SET SESSION group_concat_max_len = #{@index.local_options[:group_concat_max_len]}"
110
+ end
111
+
112
+ source.sql_query_pre += [adapter.utf8_query_pre].compact if utf8?
113
+ end
114
+
115
+ def set_source_settings(source)
116
+ config = ThinkingSphinx::Configuration.instance
117
+ config.source_options.each do |key, value|
118
+ source.send("#{key}=".to_sym, value)
119
+ end
120
+
121
+ source_options = ThinkingSphinx::Configuration::SourceOptions
122
+ @options.each do |key, value|
123
+ if source_options.include?(key.to_s) && !value.nil?
124
+ source.send("#{key}=".to_sym, value)
125
+ end
126
+ end
127
+ end
128
+
129
+ # Returns all associations used amongst all the fields and attributes.
130
+ # This includes all associations between the model and what the actual
131
+ # columns are from.
132
+ #
133
+ def all_associations
134
+ @all_associations ||= (
135
+ # field associations
136
+ @fields.collect { |field|
137
+ field.associations.values
138
+ }.flatten +
139
+ # attribute associations
140
+ @attributes.collect { |attrib|
141
+ attrib.associations.values if attrib.include_as_association?
142
+ }.compact.flatten
143
+ ).uniq.collect { |assoc|
144
+ # get ancestors as well as column-level associations
145
+ assoc.ancestors
146
+ }.flatten.uniq
147
+ end
148
+
149
+ def utf8?
150
+ @index.options[:charset_type] =~ /utf-8|zh_cn.utf-8/
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,131 @@
1
+ require 'fileutils'
2
+
3
+ namespace :thinking_sphinx do
4
+ task :app_env do
5
+ if defined?(RAILS_ROOT)
6
+ Rake::Task[:environment].invoke
7
+ Rails.configuration.cache_classes = false
8
+ end
9
+
10
+ Rake::Task[:merb_env].invoke if defined?(Merb)
11
+ end
12
+
13
+ desc "Output the current Thinking Sphinx version"
14
+ task :version => :app_env do
15
+ puts "Thinking Sphinx v" + ThinkingSphinx.version
16
+ end
17
+
18
+ desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
19
+ task :running_start => :app_env do
20
+ Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
21
+ Rake::Task["thinking_sphinx:start"].invoke
22
+ end
23
+
24
+ desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
25
+ task :start => :app_env do
26
+ config = ThinkingSphinx::Configuration.instance
27
+
28
+ FileUtils.mkdir_p config.searchd_file_path
29
+ raise RuntimeError, "searchd is already running." if sphinx_running?
30
+
31
+ Dir["#{config.searchd_file_path}/*.spl"].each { |file| File.delete(file) }
32
+
33
+ config.controller.start
34
+
35
+ if sphinx_running?
36
+ puts "Started successfully (pid #{sphinx_pid})."
37
+ else
38
+ puts "Failed to start searchd daemon. Check #{config.searchd_log_file}"
39
+ end
40
+ end
41
+
42
+ desc "Stop Sphinx using Thinking Sphinx's settings"
43
+ task :stop => :app_env do
44
+ unless sphinx_running?
45
+ puts "searchd is not running"
46
+ else
47
+ config = ThinkingSphinx::Configuration.instance
48
+ pid = sphinx_pid
49
+ config.controller.stop
50
+ begin
51
+ Timeout.timeout 5 do
52
+ while sphinx_running?
53
+ sleep 0.01
54
+ end
55
+ end
56
+ rescue Timeout::Error
57
+ puts "Could not stop sphinx (pid #{pid})!"
58
+ else
59
+ puts "Stopped search daemon (pid #{pid})."
60
+ end
61
+ end
62
+ end
63
+
64
+ desc "Restart Sphinx"
65
+ task :restart => [:app_env, :stop, :start]
66
+
67
+ desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
68
+ task :configure => :app_env do
69
+ config = ThinkingSphinx::Configuration.instance
70
+ puts "Generating Configuration to #{config.config_file}"
71
+ config.build
72
+ end
73
+
74
+ desc "Index data for Sphinx using Thinking Sphinx's settings"
75
+ task :index => :app_env do
76
+ config = ThinkingSphinx::Configuration.instance
77
+ unless ENV["INDEX_ONLY"] == "true"
78
+ puts "Generating Configuration to #{config.config_file}"
79
+ config.build
80
+ end
81
+
82
+ FileUtils.mkdir_p config.searchd_file_path
83
+ config.controller.index :verbose => true
84
+ end
85
+
86
+ desc "Reindex Sphinx without regenerating the configuration file"
87
+ task :reindex => :app_env do
88
+ config = ThinkingSphinx::Configuration.instance
89
+ FileUtils.mkdir_p config.searchd_file_path
90
+ puts config.controller.index
91
+ end
92
+
93
+ desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
94
+ task :rebuild => :app_env do
95
+ Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
96
+ Rake::Task["thinking_sphinx:index"].invoke
97
+ Rake::Task["thinking_sphinx:start"].invoke
98
+ end
99
+ end
100
+
101
+ namespace :ts do
102
+ desc "Output the current Thinking Sphinx version"
103
+ task :version => "thinking_sphinx:version"
104
+ desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
105
+ task :run => "thinking_sphinx:running_start"
106
+ desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
107
+ task :start => "thinking_sphinx:start"
108
+ desc "Stop Sphinx using Thinking Sphinx's settings"
109
+ task :stop => "thinking_sphinx:stop"
110
+ desc "Index data for Sphinx using Thinking Sphinx's settings"
111
+ task :in => "thinking_sphinx:index"
112
+ task :index => "thinking_sphinx:index"
113
+ desc "Reindex Sphinx without regenerating the configuration file"
114
+ task :reindex => "thinking_sphinx:reindex"
115
+ desc "Restart Sphinx"
116
+ task :restart => "thinking_sphinx:restart"
117
+ desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
118
+ task :conf => "thinking_sphinx:configure"
119
+ desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
120
+ task :config => "thinking_sphinx:configure"
121
+ desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
122
+ task :rebuild => "thinking_sphinx:rebuild"
123
+ end
124
+
125
+ def sphinx_pid
126
+ ThinkingSphinx.sphinx_pid
127
+ end
128
+
129
+ def sphinx_running?
130
+ ThinkingSphinx.sphinx_running?
131
+ end
@@ -0,0 +1,52 @@
1
+ class ThinkingSphinx::Test
2
+ def self.init(suppress_delta_output = true)
3
+ set_flags suppress_delta_output
4
+ create_indexes_folder
5
+ end
6
+
7
+ def self.start
8
+ config.build
9
+ config.controller.index
10
+ config.controller.start
11
+ end
12
+
13
+ def self.start_with_autostop
14
+ autostop
15
+ start
16
+ end
17
+
18
+ def self.stop
19
+ config.controller.stop
20
+ sleep(0.5) # Ensure Sphinx has shut down completely
21
+ end
22
+
23
+ def self.autostop
24
+ Kernel.at_exit do
25
+ ThinkingSphinx::Test.stop
26
+ end
27
+ end
28
+
29
+ def self.run(&block)
30
+ start
31
+ yield
32
+ stop
33
+ end
34
+
35
+ def self.config
36
+ @config ||= ::ThinkingSphinx::Configuration.instance
37
+ end
38
+
39
+ def self.index(*indexes)
40
+ config.controller.index *indexes
41
+ end
42
+
43
+ def self.set_flags(suppress_delta_output)
44
+ ::ThinkingSphinx.deltas_enabled = true
45
+ ::ThinkingSphinx.updates_enabled = true
46
+ ::ThinkingSphinx.suppress_delta_output = suppress_delta_output
47
+ end
48
+
49
+ def self.create_indexes_folder
50
+ FileUtils.mkdir_p config.searchd_file_path
51
+ end
52
+ end
@@ -0,0 +1,225 @@
1
+ require 'active_record'
2
+ require 'after_commit'
3
+ require 'yaml'
4
+ require 'cgi'
5
+ require 'riddle'
6
+
7
+ require 'thinking_sphinx/auto_version'
8
+ require 'thinking_sphinx/core/array'
9
+ require 'thinking_sphinx/core/string'
10
+ require 'thinking_sphinx/property'
11
+ require 'thinking_sphinx/active_record'
12
+ require 'thinking_sphinx/association'
13
+ require 'thinking_sphinx/attribute'
14
+ require 'thinking_sphinx/configuration'
15
+ require 'thinking_sphinx/context'
16
+ require 'thinking_sphinx/excerpter'
17
+ require 'thinking_sphinx/facet'
18
+ require 'thinking_sphinx/class_facet'
19
+ require 'thinking_sphinx/facet_search'
20
+ require 'thinking_sphinx/field'
21
+ require 'thinking_sphinx/index'
22
+ require 'thinking_sphinx/source'
23
+ require 'thinking_sphinx/rails_additions'
24
+ require 'thinking_sphinx/search'
25
+ require 'thinking_sphinx/search_methods'
26
+ require 'thinking_sphinx/deltas'
27
+
28
+ require 'thinking_sphinx/adapters/abstract_adapter'
29
+ require 'thinking_sphinx/adapters/mysql_adapter'
30
+ require 'thinking_sphinx/adapters/postgresql_adapter'
31
+
32
+ ActiveRecord::Base.send(:include, ThinkingSphinx::ActiveRecord)
33
+
34
+ Merb::Plugins.add_rakefiles(
35
+ File.join(File.dirname(__FILE__), "thinking_sphinx", "tasks")
36
+ ) if defined?(Merb)
37
+
38
+ module ThinkingSphinx
39
+ # A ConnectionError will get thrown when a connection to Sphinx can't be
40
+ # made.
41
+ class ConnectionError < StandardError
42
+ end
43
+
44
+ # A StaleIdsException is thrown by Collection.instances_from_matches if there
45
+ # are records in Sphinx but not in the database, so the search can be retried.
46
+ class StaleIdsException < StandardError
47
+ attr_accessor :ids
48
+ def initialize(ids)
49
+ self.ids = ids
50
+ end
51
+ end
52
+
53
+ # The current version of Thinking Sphinx.
54
+ #
55
+ # @return [String] The version number as a string
56
+ #
57
+ def self.version
58
+ open(File.join(File.dirname(__FILE__), '../VERSION')) { |f|
59
+ f.read.strip
60
+ }
61
+ end
62
+
63
+ # The collection of indexed models. Keep in mind that Rails lazily loads
64
+ # its classes, so this may not actually be populated with _all_ the models
65
+ # that have Sphinx indexes.
66
+ def self.context
67
+ if Thread.current[:thinking_sphinx_context].nil?
68
+ Thread.current[:thinking_sphinx_context] = ThinkingSphinx::Context.new
69
+ Thread.current[:thinking_sphinx_context].prepare
70
+ end
71
+
72
+ Thread.current[:thinking_sphinx_context]
73
+ end
74
+
75
+ def self.reset_context!
76
+ Thread.current[:thinking_sphinx_context] = nil
77
+ end
78
+
79
+ def self.unique_id_expression(offset = nil)
80
+ "* #{context.indexed_models.size} + #{offset || 0}"
81
+ end
82
+
83
+ # Check if index definition is disabled.
84
+ #
85
+ def self.define_indexes?
86
+ if Thread.current[:thinking_sphinx_define_indexes].nil?
87
+ Thread.current[:thinking_sphinx_define_indexes] = true
88
+ end
89
+
90
+ Thread.current[:thinking_sphinx_define_indexes]
91
+ end
92
+
93
+ # Enable/disable indexes - you may want to do this while migrating data.
94
+ #
95
+ # ThinkingSphinx.define_indexes = false
96
+ #
97
+ def self.define_indexes=(value)
98
+ Thread.current[:thinking_sphinx_define_indexes] = value
99
+ end
100
+
101
+ # Check if delta indexing is enabled.
102
+ #
103
+ def self.deltas_enabled?
104
+ if Thread.current[:thinking_sphinx_deltas_enabled].nil?
105
+ return true
106
+ end
107
+ Thread.current[:thinking_sphinx_deltas_enabled]
108
+ end
109
+
110
+ # Enable/disable all delta indexing.
111
+ #
112
+ # ThinkingSphinx.deltas_enabled = false
113
+ #
114
+ def self.deltas_enabled=(value)
115
+ Thread.current[:thinking_sphinx_deltas_enabled] = value
116
+ end
117
+
118
+ # Check if updates are enabled. True by default, unless within the test
119
+ # environment.
120
+ #
121
+ def self.updates_enabled?
122
+ if Thread.current[:thinking_sphinx_updates_enabled].nil?
123
+ return true
124
+ end
125
+ Thread.current[:thinking_sphinx_updates_enabled]
126
+ end
127
+
128
+ # Enable/disable updates to Sphinx
129
+ #
130
+ # ThinkingSphinx.updates_enabled = false
131
+ #
132
+ def self.updates_enabled=(value)
133
+ Thread.current[:thinking_sphinx_updates_enabled] = value
134
+ end
135
+
136
+ def self.suppress_delta_output?
137
+ Thread.current[:thinking_sphinx_suppress_delta_output] ||= false
138
+ end
139
+
140
+ def self.suppress_delta_output=(value)
141
+ Thread.current[:thinking_sphinx_suppress_delta_output] = value
142
+ end
143
+
144
+ # Checks to see if MySQL will allow simplistic GROUP BY statements. If not,
145
+ # or if not using MySQL, this will return false.
146
+ #
147
+ def self.use_group_by_shortcut?
148
+ if Thread.current[:thinking_sphinx_use_group_by_shortcut].nil?
149
+ Thread.current[:thinking_sphinx_use_group_by_shortcut] = !!(
150
+ mysql? && ::ActiveRecord::Base.connection.select_all(
151
+ "SELECT @@global.sql_mode, @@session.sql_mode;"
152
+ ).all? { |key,value| value.nil? || value[/ONLY_FULL_GROUP_BY/].nil? }
153
+ )
154
+ end
155
+
156
+ Thread.current[:thinking_sphinx_use_group_by_shortcut]
157
+ end
158
+
159
+ # An indication of whether Sphinx is running on a remote machine instead of
160
+ # the same machine.
161
+ #
162
+ def self.remote_sphinx?
163
+ Thread.current[:thinking_sphinx_remote_sphinx] ||= false
164
+ end
165
+
166
+ # Tells Thinking Sphinx that Sphinx is running on a different machine, and
167
+ # thus it can't reliably guess whether it is running or not (ie: the
168
+ # #sphinx_running? method), and so just assumes it is.
169
+ #
170
+ # Useful for multi-machine deployments. Set it in your production.rb file.
171
+ #
172
+ # ThinkingSphinx.remote_sphinx = true
173
+ #
174
+ def self.remote_sphinx=(value)
175
+ Thread.current[:thinking_sphinx_remote_sphinx] = value
176
+ end
177
+
178
+ # Check if Sphinx is running. If remote_sphinx is set to true (indicating
179
+ # Sphinx is on a different machine), this will always return true, and you
180
+ # will have to handle any connection errors yourself.
181
+ #
182
+ def self.sphinx_running?
183
+ remote_sphinx? || sphinx_running_by_pid?
184
+ end
185
+
186
+ # Check if Sphinx is actually running, provided the pid is on the same
187
+ # machine as this code.
188
+ #
189
+ def self.sphinx_running_by_pid?
190
+ !!sphinx_pid && pid_active?(sphinx_pid)
191
+ end
192
+
193
+ def self.sphinx_pid
194
+ if File.exists?(ThinkingSphinx::Configuration.instance.pid_file)
195
+ File.read(ThinkingSphinx::Configuration.instance.pid_file)[/\d+/]
196
+ else
197
+ nil
198
+ end
199
+ end
200
+
201
+ def self.pid_active?(pid)
202
+ !!Process.kill(0, pid.to_i)
203
+ rescue Exception => e
204
+ false
205
+ end
206
+
207
+ def self.microsoft?
208
+ RUBY_PLATFORM =~ /mswin/
209
+ end
210
+
211
+ def self.jruby?
212
+ defined?(JRUBY_VERSION)
213
+ end
214
+
215
+ def self.mysql?
216
+ ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlAdapter" ||
217
+ ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlplusAdapter" || (
218
+ jruby? && ::ActiveRecord::Base.connection.config[:adapter] == "jdbcmysql"
219
+ )
220
+ end
221
+
222
+ extend ThinkingSphinx::SearchMethods::ClassMethods
223
+ end
224
+
225
+ ThinkingSphinx::AutoVersion.detect
data/rails/init.rb ADDED
@@ -0,0 +1,16 @@
1
+ Dir[File.join(File.dirname(__FILE__), '../vendor/*/lib')].each do |path|
2
+ $LOAD_PATH.unshift path
3
+ end
4
+
5
+ require 'thinking_sphinx'
6
+ require 'action_controller/dispatcher'
7
+
8
+ ActionController::Dispatcher.to_prepare :thinking_sphinx do
9
+ # Force internationalisation to be loaded.
10
+ if Rails::VERSION::STRING.to_f > 2.2
11
+ I18n.backend.reload!
12
+ I18n.backend.available_locales
13
+ elsif Rails::VERSION::STRING.to_f > 2.1
14
+ I18n.backend.load_translations(*I18n.load_path)
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ require File.join(
2
+ File.dirname(__FILE__), '../lib/thinking_sphinx/deploy/capistrano'
3
+ )
@@ -0,0 +1,32 @@
1
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Ellie','K','Ford','38 Mills Street','Eagle Farm Bc','QLD','4009','Ellie.K.Ford@mailinator.com','1970/1/23 00:00:00', 3, 'CricketTeam');
2
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Aaliyah','E','Allen','71 Murphy Street','Wyola West','WA','6407','Aaliyah.E.Allen@dodgit.com','1980/3/23 00:00:00', 3, 'CricketTeam');
3
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Callum','C','Miah','89 Dalgarno Street','Bullawa Creek','NSW','2390','Callum.C.Miah@trashymail.com','1973/3/25 00:00:00', 3, 'CricketTeam');
4
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Finley','L','Buckley','18 Queen Street','Manly Vale','NSW','2093','Finley.L.Buckley@spambob.com','1962/11/20 00:00:00', 3, 'CricketTeam');
5
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Poppy','A','Hilton','36 Nerrigundah Drive','Nyora','VIC','3987','Poppy.A.Hilton@dodgit.com','1972/10/30 00:00:00', 3, 'CricketTeam');
6
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Eloise','Z','Kennedy','18 Mt Berryman Road','Lilydale','QLD','4344','Eloise.Z.Kennedy@spambob.com','1973/9/28 00:00:00', 3, 'CricketTeam');
7
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Shannon','L','Manning','60 Ocean Pde','Greenvale','QLD','4816','Shannon.L.Manning@dodgit.com','1956/6/13 00:00:00', 3, 'CricketTeam');
8
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Oscar','C','Lawson','43 Feather Street','Battery Hill','QLD','4551','Oscar.C.Lawson@spambob.com','1979/10/17 00:00:00', 3, 'CricketTeam');
9
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('female','Sofia','K','Bray','26 Clifton Street','Pental Island','VIC','3586','Sofia.K.Bray@mailinator.com','1970/5/10 00:00:00', 3, 'CricketTeam');
10
+ insert into `people` (gender, first_name, middle_initial, last_name, street_address, city, state, postcode, email, birthday, team_id, team_type) values('male','Andrew','N','Byrne','35 Cecil Street','Monash Park','NSW','2111','Andrew.N.Byrne@spambob.com','1983/2/16 00:00:00', 3, 'CricketTeam');
11
+
12
+ insert into `alphas` (name) values ('one');
13
+ insert into `alphas` (name) values ('two');
14
+ insert into `alphas` (name) values ('three');
15
+ insert into `alphas` (name) values ('four');
16
+ insert into `alphas` (name) values ('five');
17
+ insert into `alphas` (name) values ('six');
18
+ insert into `alphas` (name) values ('seven');
19
+ insert into `alphas` (name) values ('eight');
20
+ insert into `alphas` (name) values ('nine');
21
+ insert into `alphas` (name) values ('ten');
22
+
23
+ insert into `betas` (name) values ('one');
24
+ insert into `betas` (name) values ('two');
25
+ insert into `betas` (name) values ('three');
26
+ insert into `betas` (name) values ('four');
27
+ insert into `betas` (name) values ('five');
28
+ insert into `betas` (name) values ('six');
29
+ insert into `betas` (name) values ('seven');
30
+ insert into `betas` (name) values ('eight');
31
+ insert into `betas` (name) values ('nine');
32
+ insert into `betas` (name) values ('ten');
@@ -0,0 +1,3 @@
1
+ username: root
2
+ password:
3
+ host: localhost