skalee-thinking-sphinx 1.3.14.1

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