sayso-thinking-sphinx 2.0.3.001

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/LICENCE +20 -0
  2. data/README.textile +251 -0
  3. data/VERSION +1 -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 +168 -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 +197 -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/fixtures/alphas.rb +10 -0
  38. data/features/thinking_sphinx/db/fixtures/authors.rb +1 -0
  39. data/features/thinking_sphinx/db/fixtures/betas.rb +11 -0
  40. data/features/thinking_sphinx/db/fixtures/boxes.rb +9 -0
  41. data/features/thinking_sphinx/db/fixtures/categories.rb +1 -0
  42. data/features/thinking_sphinx/db/fixtures/cats.rb +3 -0
  43. data/features/thinking_sphinx/db/fixtures/comments.rb +24 -0
  44. data/features/thinking_sphinx/db/fixtures/developers.rb +31 -0
  45. data/features/thinking_sphinx/db/fixtures/dogs.rb +3 -0
  46. data/features/thinking_sphinx/db/fixtures/extensible_betas.rb +10 -0
  47. data/features/thinking_sphinx/db/fixtures/foxes.rb +3 -0
  48. data/features/thinking_sphinx/db/fixtures/gammas.rb +10 -0
  49. data/features/thinking_sphinx/db/fixtures/music.rb +4 -0
  50. data/features/thinking_sphinx/db/fixtures/people.rb +1001 -0
  51. data/features/thinking_sphinx/db/fixtures/posts.rb +6 -0
  52. data/features/thinking_sphinx/db/fixtures/robots.rb +14 -0
  53. data/features/thinking_sphinx/db/fixtures/tags.rb +27 -0
  54. data/features/thinking_sphinx/db/migrations/create_alphas.rb +8 -0
  55. data/features/thinking_sphinx/db/migrations/create_animals.rb +5 -0
  56. data/features/thinking_sphinx/db/migrations/create_authors.rb +3 -0
  57. data/features/thinking_sphinx/db/migrations/create_authors_posts.rb +6 -0
  58. data/features/thinking_sphinx/db/migrations/create_betas.rb +5 -0
  59. data/features/thinking_sphinx/db/migrations/create_boxes.rb +5 -0
  60. data/features/thinking_sphinx/db/migrations/create_categories.rb +3 -0
  61. data/features/thinking_sphinx/db/migrations/create_comments.rb +10 -0
  62. data/features/thinking_sphinx/db/migrations/create_developers.rb +7 -0
  63. data/features/thinking_sphinx/db/migrations/create_extensible_betas.rb +5 -0
  64. data/features/thinking_sphinx/db/migrations/create_gammas.rb +3 -0
  65. data/features/thinking_sphinx/db/migrations/create_genres.rb +3 -0
  66. data/features/thinking_sphinx/db/migrations/create_music.rb +6 -0
  67. data/features/thinking_sphinx/db/migrations/create_people.rb +13 -0
  68. data/features/thinking_sphinx/db/migrations/create_posts.rb +5 -0
  69. data/features/thinking_sphinx/db/migrations/create_robots.rb +4 -0
  70. data/features/thinking_sphinx/db/migrations/create_taggings.rb +5 -0
  71. data/features/thinking_sphinx/db/migrations/create_tags.rb +4 -0
  72. data/features/thinking_sphinx/models/alpha.rb +23 -0
  73. data/features/thinking_sphinx/models/andrew.rb +17 -0
  74. data/features/thinking_sphinx/models/animal.rb +5 -0
  75. data/features/thinking_sphinx/models/author.rb +3 -0
  76. data/features/thinking_sphinx/models/beta.rb +13 -0
  77. data/features/thinking_sphinx/models/box.rb +8 -0
  78. data/features/thinking_sphinx/models/cat.rb +3 -0
  79. data/features/thinking_sphinx/models/category.rb +4 -0
  80. data/features/thinking_sphinx/models/comment.rb +10 -0
  81. data/features/thinking_sphinx/models/developer.rb +20 -0
  82. data/features/thinking_sphinx/models/dog.rb +3 -0
  83. data/features/thinking_sphinx/models/extensible_beta.rb +9 -0
  84. data/features/thinking_sphinx/models/fox.rb +5 -0
  85. data/features/thinking_sphinx/models/gamma.rb +5 -0
  86. data/features/thinking_sphinx/models/genre.rb +3 -0
  87. data/features/thinking_sphinx/models/medium.rb +5 -0
  88. data/features/thinking_sphinx/models/music.rb +8 -0
  89. data/features/thinking_sphinx/models/person.rb +24 -0
  90. data/features/thinking_sphinx/models/post.rb +21 -0
  91. data/features/thinking_sphinx/models/robot.rb +12 -0
  92. data/features/thinking_sphinx/models/tag.rb +3 -0
  93. data/features/thinking_sphinx/models/tagging.rb +4 -0
  94. data/lib/cucumber/thinking_sphinx/external_world.rb +12 -0
  95. data/lib/cucumber/thinking_sphinx/internal_world.rb +127 -0
  96. data/lib/cucumber/thinking_sphinx/sql_logger.rb +20 -0
  97. data/lib/thinking-sphinx.rb +1 -0
  98. data/lib/thinking_sphinx.rb +301 -0
  99. data/lib/thinking_sphinx/action_controller.rb +31 -0
  100. data/lib/thinking_sphinx/active_record.rb +352 -0
  101. data/lib/thinking_sphinx/active_record/attribute_updates.rb +52 -0
  102. data/lib/thinking_sphinx/active_record/delta.rb +92 -0
  103. data/lib/thinking_sphinx/active_record/has_many_association.rb +36 -0
  104. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +21 -0
  105. data/lib/thinking_sphinx/active_record/log_subscriber.rb +61 -0
  106. data/lib/thinking_sphinx/active_record/scopes.rb +93 -0
  107. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +87 -0
  108. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +58 -0
  109. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +153 -0
  110. data/lib/thinking_sphinx/association.rb +169 -0
  111. data/lib/thinking_sphinx/attribute.rb +389 -0
  112. data/lib/thinking_sphinx/auto_version.rb +38 -0
  113. data/lib/thinking_sphinx/bundled_search.rb +44 -0
  114. data/lib/thinking_sphinx/class_facet.rb +16 -0
  115. data/lib/thinking_sphinx/configuration.rb +355 -0
  116. data/lib/thinking_sphinx/context.rb +76 -0
  117. data/lib/thinking_sphinx/core/string.rb +15 -0
  118. data/lib/thinking_sphinx/deltas.rb +28 -0
  119. data/lib/thinking_sphinx/deltas/default_delta.rb +62 -0
  120. data/lib/thinking_sphinx/deploy/capistrano.rb +101 -0
  121. data/lib/thinking_sphinx/excerpter.rb +23 -0
  122. data/lib/thinking_sphinx/facet.rb +127 -0
  123. data/lib/thinking_sphinx/facet_search.rb +166 -0
  124. data/lib/thinking_sphinx/field.rb +82 -0
  125. data/lib/thinking_sphinx/index.rb +157 -0
  126. data/lib/thinking_sphinx/index/builder.rb +312 -0
  127. data/lib/thinking_sphinx/index/faux_column.rb +118 -0
  128. data/lib/thinking_sphinx/join.rb +37 -0
  129. data/lib/thinking_sphinx/property.rb +185 -0
  130. data/lib/thinking_sphinx/railtie.rb +46 -0
  131. data/lib/thinking_sphinx/search.rb +950 -0
  132. data/lib/thinking_sphinx/search_methods.rb +439 -0
  133. data/lib/thinking_sphinx/source.rb +163 -0
  134. data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
  135. data/lib/thinking_sphinx/source/sql.rb +148 -0
  136. data/lib/thinking_sphinx/tasks.rb +139 -0
  137. data/lib/thinking_sphinx/test.rb +55 -0
  138. data/spec/thinking_sphinx/active_record/delta_spec.rb +128 -0
  139. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +72 -0
  140. data/spec/thinking_sphinx/active_record/scopes_spec.rb +176 -0
  141. data/spec/thinking_sphinx/active_record_spec.rb +576 -0
  142. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +145 -0
  143. data/spec/thinking_sphinx/association_spec.rb +216 -0
  144. data/spec/thinking_sphinx/attribute_spec.rb +560 -0
  145. data/spec/thinking_sphinx/auto_version_spec.rb +63 -0
  146. data/spec/thinking_sphinx/configuration_spec.rb +288 -0
  147. data/spec/thinking_sphinx/context_spec.rb +128 -0
  148. data/spec/thinking_sphinx/core/array_spec.rb +9 -0
  149. data/spec/thinking_sphinx/core/string_spec.rb +9 -0
  150. data/spec/thinking_sphinx/excerpter_spec.rb +49 -0
  151. data/spec/thinking_sphinx/facet_search_spec.rb +170 -0
  152. data/spec/thinking_sphinx/facet_spec.rb +359 -0
  153. data/spec/thinking_sphinx/field_spec.rb +127 -0
  154. data/spec/thinking_sphinx/index/builder_spec.rb +508 -0
  155. data/spec/thinking_sphinx/index/faux_column_spec.rb +36 -0
  156. data/spec/thinking_sphinx/index_spec.rb +183 -0
  157. data/spec/thinking_sphinx/search_methods_spec.rb +156 -0
  158. data/spec/thinking_sphinx/search_spec.rb +1387 -0
  159. data/spec/thinking_sphinx/source_spec.rb +253 -0
  160. data/spec/thinking_sphinx/test_spec.rb +20 -0
  161. data/spec/thinking_sphinx_spec.rb +203 -0
  162. data/tasks/distribution.rb +33 -0
  163. data/tasks/testing.rb +80 -0
  164. metadata +509 -0
@@ -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,127 @@
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'
20
+ @database = 'thinking_sphinx'
21
+ @username = 'thinking_sphinx'
22
+ # @password = 'thinking_sphinx'
23
+ @host = 'localhost'
24
+ end
25
+
26
+ def setup
27
+ make_temporary_directory
28
+
29
+ configure_cleanup
30
+ configure_thinking_sphinx
31
+ configure_active_record
32
+
33
+ prepare_data
34
+ setup_sphinx
35
+
36
+ self
37
+ end
38
+
39
+ def configure_database
40
+ ActiveRecord::Base.establish_connection database_settings
41
+ self
42
+ end
43
+
44
+ private
45
+
46
+ def config
47
+ @config ||= ::ThinkingSphinx::Configuration.instance
48
+ end
49
+
50
+ def make_temporary_directory
51
+ FileUtils.mkdir_p temporary_directory
52
+ Dir["#{temporary_directory}/*"].each do |file|
53
+ FileUtils.rm_rf file
54
+ end
55
+ end
56
+
57
+ def configure_thinking_sphinx
58
+ config.config_file = "#{temporary_directory}/sphinx.conf"
59
+ config.searchd_log_file = "#{temporary_directory}/searchd.log"
60
+ config.query_log_file = "#{temporary_directory}/searchd.query.log"
61
+ config.pid_file = "#{temporary_directory}/searchd.pid"
62
+ config.searchd_file_path = "#{temporary_directory}/indexes/"
63
+
64
+ ::ThinkingSphinx.suppress_delta_output = true
65
+ end
66
+
67
+ def configure_cleanup
68
+ Kernel.at_exit do
69
+ ::ThinkingSphinx::Configuration.instance.controller.stop
70
+ sleep(0.5) # Ensure Sphinx has shut down completely
71
+ ::ThinkingSphinx::ActiveRecord::LogSubscriber.logger.close
72
+ end
73
+ end
74
+
75
+ def yaml_database_settings
76
+ return {} unless File.exist?(@database_file)
77
+
78
+ YAML.load open(@database_file)
79
+ end
80
+
81
+ def database_settings
82
+ {
83
+ 'adapter' => @adapter,
84
+ 'database' => @database,
85
+ 'username' => @username,
86
+ 'password' => @password,
87
+ 'host' => @host
88
+ }.merge yaml_database_settings
89
+ end
90
+
91
+ def configure_active_record
92
+ ::ThinkingSphinx::ActiveRecord::LogSubscriber.logger = Logger.new(
93
+ open("#{temporary_directory}/active_record.log", "a")
94
+ )
95
+
96
+ ActiveRecord::Base.connection.class.send(
97
+ :include, Cucumber::ThinkingSphinx::SqlLogger
98
+ )
99
+ end
100
+
101
+ def prepare_data
102
+ ::ThinkingSphinx.deltas_enabled = false
103
+
104
+ load_files migrations_directory
105
+ load_files models_directory
106
+ load_files fixtures_directory
107
+
108
+ ::ThinkingSphinx.deltas_enabled = true
109
+ end
110
+
111
+ def load_files(path)
112
+ files = Dir["#{path}/*.rb"].sort!
113
+ files.each do |file|
114
+ require file.gsub(/\.rb$/, '')
115
+ end
116
+ end
117
+
118
+ def setup_sphinx
119
+ FileUtils.mkdir_p config.searchd_file_path
120
+
121
+ config.build
122
+ config.controller.index
123
+ config.controller.start
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,20 @@
1
+ module Cucumber
2
+ module ThinkingSphinx
3
+ module SqlLogger
4
+ def self.included(base)
5
+ base.send :alias_method_chain, :execute, :query_record
6
+ end
7
+
8
+ IGNORED_SQL = [
9
+ /^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/,
10
+ /^SELECT @@ROWCOUNT/, /^SHOW FIELDS/
11
+ ]
12
+
13
+ def execute_with_query_record(sql, name = nil, &block)
14
+ $queries_executed ||= []
15
+ $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
16
+ execute_without_query_record(sql, name, &block)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1 @@
1
+ require 'thinking_sphinx'
@@ -0,0 +1,301 @@
1
+ require 'thread'
2
+ require 'active_record'
3
+ require 'yaml'
4
+ require 'riddle'
5
+
6
+ require 'thinking_sphinx/auto_version'
7
+ require 'thinking_sphinx/core/string'
8
+ require 'thinking_sphinx/property'
9
+ require 'thinking_sphinx/active_record'
10
+ require 'thinking_sphinx/association'
11
+ require 'thinking_sphinx/attribute'
12
+ require 'thinking_sphinx/bundled_search'
13
+ require 'thinking_sphinx/configuration'
14
+ require 'thinking_sphinx/context'
15
+ require 'thinking_sphinx/excerpter'
16
+ require 'thinking_sphinx/facet'
17
+ require 'thinking_sphinx/class_facet'
18
+ require 'thinking_sphinx/facet_search'
19
+ require 'thinking_sphinx/field'
20
+ require 'thinking_sphinx/index'
21
+ require 'thinking_sphinx/join'
22
+ require 'thinking_sphinx/source'
23
+ require 'thinking_sphinx/search'
24
+ require 'thinking_sphinx/search_methods'
25
+ require 'thinking_sphinx/deltas'
26
+
27
+ require 'thinking_sphinx/adapters/abstract_adapter'
28
+ require 'thinking_sphinx/adapters/mysql_adapter'
29
+ require 'thinking_sphinx/adapters/postgresql_adapter'
30
+
31
+ require 'thinking_sphinx/railtie' if defined?(Rails)
32
+
33
+ module ThinkingSphinx
34
+ mattr_accessor :database_adapter
35
+
36
+ # A ConnectionError will get thrown when a connection to Sphinx can't be
37
+ # made.
38
+ class ConnectionError < StandardError
39
+ end
40
+
41
+ # A StaleIdsException is thrown by Collection.instances_from_matches if there
42
+ # are records in Sphinx but not in the database, so the search can be retried.
43
+ class StaleIdsException < StandardError
44
+ attr_accessor :ids
45
+ def initialize(ids)
46
+ self.ids = ids
47
+ end
48
+ end
49
+
50
+ # A SphinxError occurs when Sphinx responds with an error due to problematic
51
+ # queries or indexes.
52
+ class SphinxError < RuntimeError
53
+ attr_accessor :results
54
+ def initialize(message = nil, results = nil)
55
+ super(message)
56
+ self.results = results
57
+ end
58
+ end
59
+
60
+ # The current version of Thinking Sphinx.
61
+ #
62
+ # @return [String] The version number as a string
63
+ #
64
+ def self.version
65
+ open(File.join(File.dirname(__FILE__), '../VERSION')) { |f|
66
+ f.read.strip
67
+ }
68
+ end
69
+
70
+ # The collection of indexed models. Keep in mind that Rails lazily loads
71
+ # its classes, so this may not actually be populated with _all_ the models
72
+ # that have Sphinx indexes.
73
+ @@sphinx_mutex = Mutex.new
74
+ @@context = nil
75
+ @@define_indexes = true
76
+ @@deltas_enabled = nil
77
+ @@updates_enabled = nil
78
+ @@suppress_delta_output = false
79
+ @@remote_sphinx = false
80
+ @@use_group_by_shortcut = nil
81
+
82
+ def self.mutex
83
+ @@sphinx_mutex
84
+ end
85
+
86
+ def self.context
87
+ if @@context.nil?
88
+ mutex.synchronize do
89
+ if @@context.nil?
90
+ @@context = ThinkingSphinx::Context.new
91
+ @@context.prepare
92
+ end
93
+ end
94
+ end
95
+
96
+ @@context
97
+ end
98
+
99
+ def self.reset_context!(context = nil)
100
+ mutex.synchronize do
101
+ @@context = context
102
+ end
103
+ end
104
+
105
+ def self.unique_id_expression(offset = nil)
106
+ "* #{context.indexed_models.size} + #{offset || 0}"
107
+ end
108
+
109
+ # Check if index definition is disabled.
110
+ #
111
+ def self.define_indexes?
112
+ @@define_indexes
113
+ end
114
+
115
+ # Enable/disable indexes - you may want to do this while migrating data.
116
+ #
117
+ # ThinkingSphinx.define_indexes = false
118
+ #
119
+ def self.define_indexes=(value)
120
+ mutex.synchronize do
121
+ @@define_indexes = value
122
+ end
123
+ end
124
+
125
+ # Check if delta indexing is enabled/disabled.
126
+ #
127
+ def self.deltas_enabled?
128
+ if @@deltas_enabled.nil?
129
+ mutex.synchronize do
130
+ if @@deltas_enabled.nil?
131
+ @@deltas_enabled = (
132
+ ThinkingSphinx::Configuration.environment != "test"
133
+ )
134
+ end
135
+ end
136
+ end
137
+
138
+ @@deltas_enabled && !deltas_suspended?
139
+ end
140
+
141
+ # Enable/disable delta indexing.
142
+ #
143
+ # ThinkingSphinx.deltas_enabled = false
144
+ #
145
+ def self.deltas_enabled=(value)
146
+ mutex.synchronize do
147
+ @@deltas_enabled = value
148
+ end
149
+ end
150
+
151
+ # Check if delta indexing is suspended.
152
+ #
153
+ def self.deltas_suspended?
154
+ if Thread.current[:thinking_sphinx_deltas_suspended].nil?
155
+ Thread.current[:thinking_sphinx_deltas_suspended] = false
156
+ end
157
+
158
+ Thread.current[:thinking_sphinx_deltas_suspended]
159
+ end
160
+
161
+ # Suspend/resume delta indexing.
162
+ #
163
+ # ThinkingSphinx.deltas_suspended = false
164
+ #
165
+ def self.deltas_suspended=(value)
166
+ Thread.current[:thinking_sphinx_deltas_suspended] = value
167
+ end
168
+
169
+ # Check if updates are enabled. True by default, unless within the test
170
+ # environment.
171
+ #
172
+ def self.updates_enabled?
173
+ if @@updates_enabled.nil?
174
+ mutex.synchronize do
175
+ if @@updates_enabled.nil?
176
+ @@updates_enabled = (
177
+ ThinkingSphinx::Configuration.environment != "test"
178
+ )
179
+ end
180
+ end
181
+ end
182
+
183
+ @@updates_enabled
184
+ end
185
+
186
+ # Enable/disable updates to Sphinx
187
+ #
188
+ # ThinkingSphinx.updates_enabled = false
189
+ #
190
+ def self.updates_enabled=(value)
191
+ mutex.synchronize do
192
+ @@updates_enabled = value
193
+ end
194
+ end
195
+
196
+ def self.suppress_delta_output?
197
+ @@suppress_delta_output
198
+ end
199
+
200
+ def self.suppress_delta_output=(value)
201
+ mutex.synchronize do
202
+ @@suppress_delta_output = value
203
+ end
204
+ end
205
+
206
+ # Checks to see if MySQL will allow simplistic GROUP BY statements. If not,
207
+ # or if not using MySQL, this will return false.
208
+ #
209
+ def self.use_group_by_shortcut?
210
+ if @@use_group_by_shortcut.nil?
211
+ mutex.synchronize do
212
+ if @@use_group_by_shortcut.nil?
213
+ @@use_group_by_shortcut = !!(
214
+ mysql? && ::ActiveRecord::Base.connection.select_all(
215
+ "SELECT @@global.sql_mode, @@session.sql_mode;"
216
+ ).all? { |key, value|
217
+ value.nil? || value[/ONLY_FULL_GROUP_BY/].nil?
218
+ }
219
+ )
220
+ end
221
+ end
222
+ end
223
+
224
+ @@use_group_by_shortcut
225
+ end
226
+
227
+ def self.reset_use_group_by_shortcut
228
+ mutex.synchronize do
229
+ @@use_group_by_shortcut = nil
230
+ end
231
+ end
232
+
233
+ # An indication of whether Sphinx is running on a remote machine instead of
234
+ # the same machine.
235
+ #
236
+ def self.remote_sphinx?
237
+ @@remote_sphinx
238
+ end
239
+
240
+ # Tells Thinking Sphinx that Sphinx is running on a different machine, and
241
+ # thus it can't reliably guess whether it is running or not (ie: the
242
+ # #sphinx_running? method), and so just assumes it is.
243
+ #
244
+ # Useful for multi-machine deployments. Set it in your production.rb file.
245
+ #
246
+ # ThinkingSphinx.remote_sphinx = true
247
+ #
248
+ def self.remote_sphinx=(value)
249
+ mutex.synchronize do
250
+ @@remote_sphinx = value
251
+ end
252
+ end
253
+
254
+ # Check if Sphinx is running. If remote_sphinx is set to true (indicating
255
+ # Sphinx is on a different machine), this will always return true, and you
256
+ # will have to handle any connection errors yourself.
257
+ #
258
+ def self.sphinx_running?
259
+ remote_sphinx? || sphinx_running_by_pid?
260
+ end
261
+
262
+ # Check if Sphinx is actually running, provided the pid is on the same
263
+ # machine as this code.
264
+ #
265
+ def self.sphinx_running_by_pid?
266
+ !!sphinx_pid && pid_active?(sphinx_pid)
267
+ end
268
+
269
+ def self.sphinx_pid
270
+ if File.exists?(ThinkingSphinx::Configuration.instance.pid_file)
271
+ File.read(ThinkingSphinx::Configuration.instance.pid_file)[/\d+/]
272
+ else
273
+ nil
274
+ end
275
+ end
276
+
277
+ def self.pid_active?(pid)
278
+ !!Process.kill(0, pid.to_i)
279
+ rescue Errno::EPERM => e
280
+ true
281
+ rescue Exception => e
282
+ false
283
+ end
284
+
285
+ def self.microsoft?
286
+ RUBY_PLATFORM =~ /mswin/
287
+ end
288
+
289
+ def self.jruby?
290
+ defined?(JRUBY_VERSION)
291
+ end
292
+
293
+ def self.mysql?
294
+ ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlAdapter" ||
295
+ ::ActiveRecord::Base.connection.class.name.demodulize == "MysqlplusAdapter" || (
296
+ jruby? && ::ActiveRecord::Base.connection.config[:adapter] == "jdbcmysql"
297
+ )
298
+ end
299
+
300
+ extend ThinkingSphinx::SearchMethods::ClassMethods
301
+ end