thinking-sphinx 1.2.12
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.
- data/LICENCE +20 -0
- data/README.textile +157 -0
- data/VERSION.yml +4 -0
- data/lib/thinking_sphinx.rb +211 -0
- data/lib/thinking_sphinx/active_record.rb +307 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +48 -0
- data/lib/thinking_sphinx/active_record/delta.rb +87 -0
- data/lib/thinking_sphinx/active_record/has_many_association.rb +28 -0
- data/lib/thinking_sphinx/active_record/scopes.rb +39 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +42 -0
- data/lib/thinking_sphinx/adapters/mysql_adapter.rb +54 -0
- data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +136 -0
- data/lib/thinking_sphinx/association.rb +164 -0
- data/lib/thinking_sphinx/attribute.rb +342 -0
- data/lib/thinking_sphinx/class_facet.rb +15 -0
- data/lib/thinking_sphinx/configuration.rb +282 -0
- data/lib/thinking_sphinx/core/array.rb +7 -0
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas.rb +30 -0
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +68 -0
- data/lib/thinking_sphinx/deltas/delayed_delta.rb +30 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb +24 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb +27 -0
- data/lib/thinking_sphinx/deltas/delayed_delta/job.rb +26 -0
- data/lib/thinking_sphinx/deploy/capistrano.rb +100 -0
- data/lib/thinking_sphinx/excerpter.rb +22 -0
- data/lib/thinking_sphinx/facet.rb +125 -0
- data/lib/thinking_sphinx/facet_search.rb +134 -0
- data/lib/thinking_sphinx/field.rb +82 -0
- data/lib/thinking_sphinx/index.rb +99 -0
- data/lib/thinking_sphinx/index/builder.rb +286 -0
- data/lib/thinking_sphinx/index/faux_column.rb +110 -0
- data/lib/thinking_sphinx/property.rb +162 -0
- data/lib/thinking_sphinx/rails_additions.rb +150 -0
- data/lib/thinking_sphinx/search.rb +707 -0
- data/lib/thinking_sphinx/search_methods.rb +421 -0
- data/lib/thinking_sphinx/source.rb +150 -0
- data/lib/thinking_sphinx/source/internal_properties.rb +46 -0
- data/lib/thinking_sphinx/source/sql.rb +128 -0
- data/lib/thinking_sphinx/tasks.rb +165 -0
- data/rails/init.rb +14 -0
- data/spec/lib/thinking_sphinx/active_record/delta_spec.rb +130 -0
- data/spec/lib/thinking_sphinx/active_record/has_many_association_spec.rb +49 -0
- data/spec/lib/thinking_sphinx/active_record/scopes_spec.rb +96 -0
- data/spec/lib/thinking_sphinx/active_record_spec.rb +364 -0
- data/spec/lib/thinking_sphinx/association_spec.rb +239 -0
- data/spec/lib/thinking_sphinx/attribute_spec.rb +500 -0
- data/spec/lib/thinking_sphinx/configuration_spec.rb +268 -0
- data/spec/lib/thinking_sphinx/core/array_spec.rb +9 -0
- data/spec/lib/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/lib/thinking_sphinx/excerpter_spec.rb +49 -0
- data/spec/lib/thinking_sphinx/facet_search_spec.rb +176 -0
- data/spec/lib/thinking_sphinx/facet_spec.rb +333 -0
- data/spec/lib/thinking_sphinx/field_spec.rb +154 -0
- data/spec/lib/thinking_sphinx/index/builder_spec.rb +455 -0
- data/spec/lib/thinking_sphinx/index/faux_column_spec.rb +30 -0
- data/spec/lib/thinking_sphinx/index_spec.rb +45 -0
- data/spec/lib/thinking_sphinx/rails_additions_spec.rb +203 -0
- data/spec/lib/thinking_sphinx/search_methods_spec.rb +152 -0
- data/spec/lib/thinking_sphinx/search_spec.rb +1092 -0
- data/spec/lib/thinking_sphinx/source_spec.rb +227 -0
- data/spec/lib/thinking_sphinx_spec.rb +162 -0
- data/tasks/distribution.rb +50 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +83 -0
- data/vendor/after_commit/LICENSE +20 -0
- data/vendor/after_commit/README +16 -0
- data/vendor/after_commit/Rakefile +22 -0
- data/vendor/after_commit/init.rb +8 -0
- data/vendor/after_commit/lib/after_commit.rb +45 -0
- data/vendor/after_commit/lib/after_commit/active_record.rb +114 -0
- data/vendor/after_commit/lib/after_commit/connection_adapters.rb +103 -0
- data/vendor/after_commit/test/after_commit_test.rb +53 -0
- data/vendor/delayed_job/lib/delayed/job.rb +251 -0
- data/vendor/delayed_job/lib/delayed/message_sending.rb +7 -0
- data/vendor/delayed_job/lib/delayed/performable_method.rb +55 -0
- data/vendor/delayed_job/lib/delayed/worker.rb +54 -0
- data/vendor/riddle/lib/riddle.rb +30 -0
- data/vendor/riddle/lib/riddle/client.rb +635 -0
- data/vendor/riddle/lib/riddle/client/filter.rb +53 -0
- data/vendor/riddle/lib/riddle/client/message.rb +66 -0
- data/vendor/riddle/lib/riddle/client/response.rb +84 -0
- data/vendor/riddle/lib/riddle/configuration.rb +33 -0
- data/vendor/riddle/lib/riddle/configuration/distributed_index.rb +48 -0
- data/vendor/riddle/lib/riddle/configuration/index.rb +142 -0
- data/vendor/riddle/lib/riddle/configuration/indexer.rb +19 -0
- data/vendor/riddle/lib/riddle/configuration/remote_index.rb +17 -0
- data/vendor/riddle/lib/riddle/configuration/searchd.rb +25 -0
- data/vendor/riddle/lib/riddle/configuration/section.rb +43 -0
- data/vendor/riddle/lib/riddle/configuration/source.rb +23 -0
- data/vendor/riddle/lib/riddle/configuration/sql_source.rb +34 -0
- data/vendor/riddle/lib/riddle/configuration/xml_source.rb +28 -0
- data/vendor/riddle/lib/riddle/controller.rb +53 -0
- metadata +172 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module ThinkingSphinx
|
|
2
|
+
class Source
|
|
3
|
+
module InternalProperties
|
|
4
|
+
def add_internal_attributes_and_facets
|
|
5
|
+
add_internal_attribute :sphinx_internal_id, :integer, @model.primary_key_for_sphinx.to_sym
|
|
6
|
+
add_internal_attribute :class_crc, :integer, crc_column, true
|
|
7
|
+
add_internal_attribute :subclass_crcs, :multi, subclasses_to_s
|
|
8
|
+
add_internal_attribute :sphinx_deleted, :integer, "0"
|
|
9
|
+
|
|
10
|
+
add_internal_facet :class_crc
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add_internal_attribute(name, type, contents, facet = false)
|
|
14
|
+
return unless attribute_by_alias(name).nil?
|
|
15
|
+
|
|
16
|
+
Attribute.new(self,
|
|
17
|
+
ThinkingSphinx::Index::FauxColumn.new(contents),
|
|
18
|
+
:type => type,
|
|
19
|
+
:as => name,
|
|
20
|
+
:facet => facet,
|
|
21
|
+
:admin => true
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_internal_facet(name)
|
|
26
|
+
return unless facet_by_alias(name).nil?
|
|
27
|
+
|
|
28
|
+
@model.sphinx_facets << ClassFacet.new(attribute_by_alias(name))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def attribute_by_alias(attr_alias)
|
|
32
|
+
@attributes.detect { |attrib| attrib.alias == attr_alias }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def facet_by_alias(name)
|
|
36
|
+
@model.sphinx_facets.detect { |facet| facet.name == name }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def subclasses_to_s
|
|
40
|
+
"'" + (@model.send(:subclasses).collect { |klass|
|
|
41
|
+
klass.to_crc32.to_s
|
|
42
|
+
} << @model.to_crc32.to_s).join(",") + "'"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module ThinkingSphinx
|
|
2
|
+
class Source
|
|
3
|
+
module SQL
|
|
4
|
+
# Generates the big SQL statement to get the data back for all the fields
|
|
5
|
+
# and attributes, using all the relevant association joins. If you want
|
|
6
|
+
# the version filtered for delta values, send through :delta => true in the
|
|
7
|
+
# options. Won't do much though if the index isn't set up to support a
|
|
8
|
+
# delta sibling.
|
|
9
|
+
#
|
|
10
|
+
# Examples:
|
|
11
|
+
#
|
|
12
|
+
# source.to_sql
|
|
13
|
+
# source.to_sql(:delta => true)
|
|
14
|
+
#
|
|
15
|
+
def to_sql(options={})
|
|
16
|
+
sql = <<-SQL
|
|
17
|
+
SELECT #{ sql_select_clause options[:offset] }
|
|
18
|
+
FROM #{ @model.quoted_table_name }
|
|
19
|
+
#{ all_associations.collect { |assoc| assoc.to_sql }.join(' ') }
|
|
20
|
+
#{ sql_where_clause(options) }
|
|
21
|
+
GROUP BY #{ sql_group_clause }
|
|
22
|
+
SQL
|
|
23
|
+
|
|
24
|
+
sql += " ORDER BY NULL" if adapter.sphinx_identifier == "mysql"
|
|
25
|
+
sql
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Simple helper method for the query range SQL - which is a statement that
|
|
29
|
+
# returns minimum and maximum id values. These can be filtered by delta -
|
|
30
|
+
# so pass in :delta => true to get the delta version of the SQL.
|
|
31
|
+
#
|
|
32
|
+
def to_sql_query_range(options={})
|
|
33
|
+
return nil if @index.options[:disable_range]
|
|
34
|
+
|
|
35
|
+
min_statement = adapter.convert_nulls(
|
|
36
|
+
"MIN(#{quote_column(@model.primary_key_for_sphinx)})", 1
|
|
37
|
+
)
|
|
38
|
+
max_statement = adapter.convert_nulls(
|
|
39
|
+
"MAX(#{quote_column(@model.primary_key_for_sphinx)})", 1
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
sql = "SELECT #{min_statement}, #{max_statement} " +
|
|
43
|
+
"FROM #{@model.quoted_table_name} "
|
|
44
|
+
if self.delta? && !@index.delta_object.clause(@model, options[:delta]).blank?
|
|
45
|
+
sql << "WHERE #{@index.delta_object.clause(@model, options[:delta])}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
sql
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Simple helper method for the query info SQL - which is a statement that
|
|
52
|
+
# returns the single row for a corresponding id.
|
|
53
|
+
#
|
|
54
|
+
def to_sql_query_info(offset)
|
|
55
|
+
"SELECT * FROM #{@model.quoted_table_name} WHERE " +
|
|
56
|
+
"#{quote_column(@model.primary_key_for_sphinx)} = (($id - #{offset}) / #{ThinkingSphinx.indexed_models.size})"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def sql_select_clause(offset)
|
|
60
|
+
unique_id_expr = ThinkingSphinx.unique_id_expression(offset)
|
|
61
|
+
|
|
62
|
+
(
|
|
63
|
+
["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} #{unique_id_expr} AS #{quote_column(@model.primary_key_for_sphinx)} "] +
|
|
64
|
+
@fields.collect { |field| field.to_select_sql } +
|
|
65
|
+
@attributes.collect { |attribute| attribute.to_select_sql }
|
|
66
|
+
).compact.join(", ")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def sql_where_clause(options)
|
|
70
|
+
logic = []
|
|
71
|
+
logic += [
|
|
72
|
+
"#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} >= $start",
|
|
73
|
+
"#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)} <= $end"
|
|
74
|
+
] unless @index.options[:disable_range]
|
|
75
|
+
|
|
76
|
+
if self.delta? && !@index.delta_object.clause(@model, options[:delta]).blank?
|
|
77
|
+
logic << "#{@index.delta_object.clause(@model, options[:delta])}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
logic += (@conditions || [])
|
|
81
|
+
logic.empty? ? "" : "WHERE #{logic.join(' AND ')}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def sql_group_clause
|
|
85
|
+
internal_groupings = []
|
|
86
|
+
if @model.column_names.include?(@model.inheritance_column)
|
|
87
|
+
internal_groupings << "#{@model.quoted_table_name}.#{quote_column(@model.inheritance_column)}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
(
|
|
91
|
+
["#{@model.quoted_table_name}.#{quote_column(@model.primary_key_for_sphinx)}"] +
|
|
92
|
+
@fields.collect { |field| field.to_group_sql }.compact +
|
|
93
|
+
@attributes.collect { |attribute| attribute.to_group_sql }.compact +
|
|
94
|
+
@groupings + internal_groupings
|
|
95
|
+
).join(", ")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def sql_query_pre_for_core
|
|
99
|
+
if self.delta? && !@index.delta_object.reset_query(@model).blank?
|
|
100
|
+
[@index.delta_object.reset_query(@model)]
|
|
101
|
+
else
|
|
102
|
+
[]
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def sql_query_pre_for_delta
|
|
107
|
+
[""]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def quote_column(column)
|
|
111
|
+
@model.connection.quote_column_name(column)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def crc_column
|
|
115
|
+
if @model.table_exists? &&
|
|
116
|
+
@model.column_names.include?(@model.inheritance_column)
|
|
117
|
+
|
|
118
|
+
adapter.cast_to_unsigned(adapter.convert_nulls(
|
|
119
|
+
adapter.crc(adapter.quote_with_table(@model.inheritance_column), true),
|
|
120
|
+
@model.to_crc32
|
|
121
|
+
))
|
|
122
|
+
else
|
|
123
|
+
@model.to_crc32.to_s
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
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
|
+
system! "#{config.bin_path}#{config.searchd_binary_name} --pidfile --config \"#{config.config_file}\""
|
|
34
|
+
|
|
35
|
+
sleep(2)
|
|
36
|
+
|
|
37
|
+
if sphinx_running?
|
|
38
|
+
puts "Started successfully (pid #{sphinx_pid})."
|
|
39
|
+
else
|
|
40
|
+
puts "Failed to start searchd daemon. Check #{config.searchd_log_file}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
desc "Stop Sphinx using Thinking Sphinx's settings"
|
|
45
|
+
task :stop => :app_env do
|
|
46
|
+
unless sphinx_running?
|
|
47
|
+
puts "searchd is not running"
|
|
48
|
+
else
|
|
49
|
+
config = ThinkingSphinx::Configuration.instance
|
|
50
|
+
pid = sphinx_pid
|
|
51
|
+
system! "#{config.bin_path}#{config.searchd_binary_name} --stop --config \"#{config.config_file}\""
|
|
52
|
+
puts "Stopped search daemon (pid #{pid})."
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
desc "Restart Sphinx"
|
|
57
|
+
task :restart => [:app_env, :stop, :start]
|
|
58
|
+
|
|
59
|
+
desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
|
|
60
|
+
task :configure => :app_env do
|
|
61
|
+
config = ThinkingSphinx::Configuration.instance
|
|
62
|
+
puts "Generating Configuration to #{config.config_file}"
|
|
63
|
+
config.build
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
desc "Index data for Sphinx using Thinking Sphinx's settings"
|
|
67
|
+
task :index => :app_env do
|
|
68
|
+
ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
|
|
69
|
+
|
|
70
|
+
config = ThinkingSphinx::Configuration.instance
|
|
71
|
+
unless ENV["INDEX_ONLY"] == "true"
|
|
72
|
+
puts "Generating Configuration to #{config.config_file}"
|
|
73
|
+
config.build
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
FileUtils.mkdir_p config.searchd_file_path
|
|
77
|
+
cmd = "#{config.bin_path}#{config.indexer_binary_name} --config \"#{config.config_file}\" --all"
|
|
78
|
+
cmd << " --rotate" if sphinx_running?
|
|
79
|
+
|
|
80
|
+
system! cmd
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
|
|
84
|
+
task :rebuild => :app_env do
|
|
85
|
+
Rake::Task["thinking_sphinx:stop"].invoke if sphinx_running?
|
|
86
|
+
Rake::Task["thinking_sphinx:index"].invoke
|
|
87
|
+
Rake::Task["thinking_sphinx:start"].invoke
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
namespace :index do
|
|
91
|
+
task :delta => :app_env do
|
|
92
|
+
ThinkingSphinx.indexed_models.select { |model|
|
|
93
|
+
model.constantize.sphinx_indexes.any? { |index| index.delta? }
|
|
94
|
+
}.each do |model|
|
|
95
|
+
model.constantize.sphinx_indexes.select { |index|
|
|
96
|
+
index.delta? && index.delta_object.respond_to?(:delayed_index)
|
|
97
|
+
}.each { |index|
|
|
98
|
+
index.delta_object.delayed_index(index.model)
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
desc "Process stored delta index requests"
|
|
105
|
+
task :delayed_delta => :app_env do
|
|
106
|
+
require 'delayed/worker'
|
|
107
|
+
|
|
108
|
+
Delayed::Worker.new(
|
|
109
|
+
:min_priority => ENV['MIN_PRIORITY'],
|
|
110
|
+
:max_priority => ENV['MAX_PRIORITY']
|
|
111
|
+
).start
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
namespace :ts do
|
|
116
|
+
desc "Output the current Thinking Sphinx version"
|
|
117
|
+
task :version => "thinking_sphinx:version"
|
|
118
|
+
desc "Stop if running, then start a Sphinx searchd daemon using Thinking Sphinx's settings"
|
|
119
|
+
task :run => "thinking_sphinx:running_start"
|
|
120
|
+
desc "Start a Sphinx searchd daemon using Thinking Sphinx's settings"
|
|
121
|
+
task :start => "thinking_sphinx:start"
|
|
122
|
+
desc "Stop Sphinx using Thinking Sphinx's settings"
|
|
123
|
+
task :stop => "thinking_sphinx:stop"
|
|
124
|
+
desc "Index data for Sphinx using Thinking Sphinx's settings"
|
|
125
|
+
task :in => "thinking_sphinx:index"
|
|
126
|
+
namespace :in do
|
|
127
|
+
desc "Index Thinking Sphinx datetime delta indexes"
|
|
128
|
+
task :delta => "thinking_sphinx:index:delta"
|
|
129
|
+
end
|
|
130
|
+
task :index => "thinking_sphinx:index"
|
|
131
|
+
desc "Restart Sphinx"
|
|
132
|
+
task :restart => "thinking_sphinx:restart"
|
|
133
|
+
desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
|
|
134
|
+
task :conf => "thinking_sphinx:configure"
|
|
135
|
+
desc "Generate the Sphinx configuration file using Thinking Sphinx's settings"
|
|
136
|
+
task :config => "thinking_sphinx:configure"
|
|
137
|
+
desc "Stop Sphinx (if it's running), rebuild the indexes, and start Sphinx"
|
|
138
|
+
task :rebuild => "thinking_sphinx:rebuild"
|
|
139
|
+
desc "Process stored delta index requests"
|
|
140
|
+
task :dd => "thinking_sphinx:delayed_delta"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def sphinx_pid
|
|
144
|
+
ThinkingSphinx.sphinx_pid
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def sphinx_running?
|
|
148
|
+
ThinkingSphinx.sphinx_running?
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# a fail-fast, hopefully helpful version of system
|
|
152
|
+
def system!(cmd)
|
|
153
|
+
unless system(cmd)
|
|
154
|
+
raise <<-SYSTEM_CALL_FAILED
|
|
155
|
+
The following command failed:
|
|
156
|
+
#{cmd}
|
|
157
|
+
|
|
158
|
+
This could be caused by a PATH issue in the environment of cron/passenger/etc. Your current PATH:
|
|
159
|
+
#{ENV['PATH']}
|
|
160
|
+
You can set the path to your indexer and searchd binaries using the bin_path property in config/sphinx.yml:
|
|
161
|
+
production:
|
|
162
|
+
bin_path: '/usr/local/bin'
|
|
163
|
+
SYSTEM_CALL_FAILED
|
|
164
|
+
end
|
|
165
|
+
end
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'thinking_sphinx'
|
|
2
|
+
require 'action_controller/dispatcher'
|
|
3
|
+
|
|
4
|
+
ActionController::Dispatcher.to_prepare :thinking_sphinx do
|
|
5
|
+
# Force internationalisation to be loaded.
|
|
6
|
+
if Rails::VERSION::STRING.to_f > 2.2
|
|
7
|
+
I18n.backend.reload!
|
|
8
|
+
I18n.backend.available_locales
|
|
9
|
+
elsif Rails::VERSION::STRING.to_f > 2.1
|
|
10
|
+
I18n.backend.load_translations(*I18n.load_path)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
ThinkingSphinx::Configuration.instance.load_models
|
|
14
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
require 'spec/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "ThinkingSphinx::ActiveRecord::Delta" do
|
|
4
|
+
it "should call the toggle_delta method after a save" do
|
|
5
|
+
@beta = Beta.new(:name => 'beta')
|
|
6
|
+
@beta.should_receive(:toggle_delta).and_return(true)
|
|
7
|
+
|
|
8
|
+
@beta.save
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should call the toggle_delta method after a save!" do
|
|
12
|
+
@beta = Beta.new(:name => 'beta')
|
|
13
|
+
@beta.should_receive(:toggle_delta).and_return(true)
|
|
14
|
+
|
|
15
|
+
@beta.save!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "suspended_delta method" do
|
|
19
|
+
before :each do
|
|
20
|
+
ThinkingSphinx.deltas_enabled = true
|
|
21
|
+
Person.sphinx_indexes.first.delta_object.stub!(:` => "")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should execute the argument block with deltas disabled" do
|
|
25
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).once.with(false)
|
|
26
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).once.with(true)
|
|
27
|
+
lambda { Person.suspended_delta { raise 'i was called' } }.should(
|
|
28
|
+
raise_error(Exception)
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should restore deltas_enabled to its original setting" do
|
|
33
|
+
ThinkingSphinx.deltas_enabled = false
|
|
34
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false)
|
|
35
|
+
Person.suspended_delta { 'no-op' }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should restore deltas_enabled to its original setting even if there was an exception" do
|
|
39
|
+
ThinkingSphinx.deltas_enabled = false
|
|
40
|
+
ThinkingSphinx.should_receive(:deltas_enabled=).twice.with(false)
|
|
41
|
+
lambda { Person.suspended_delta { raise 'bad error' } }.should(
|
|
42
|
+
raise_error(Exception)
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should reindex by default after the code block is run" do
|
|
47
|
+
Person.should_receive(:index_delta)
|
|
48
|
+
Person.suspended_delta { 'no-op' }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should not reindex after the code block if false is passed in" do
|
|
52
|
+
Person.should_not_receive(:index_delta)
|
|
53
|
+
Person.suspended_delta(false) { 'no-op' }
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "toggle_delta method" do
|
|
58
|
+
it "should set the delta value to true" do
|
|
59
|
+
@person = Person.new
|
|
60
|
+
|
|
61
|
+
@person.delta.should be_false
|
|
62
|
+
@person.send(:toggle_delta)
|
|
63
|
+
@person.delta.should be_true
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe "index_delta method" do
|
|
68
|
+
before :each do
|
|
69
|
+
ThinkingSphinx::Configuration.stub!(:environment => "spec")
|
|
70
|
+
ThinkingSphinx.deltas_enabled = true
|
|
71
|
+
ThinkingSphinx.updates_enabled = true
|
|
72
|
+
ThinkingSphinx.stub!(:sphinx_running? => true)
|
|
73
|
+
Person.delta_object.stub!(:` => "", :toggled => true)
|
|
74
|
+
|
|
75
|
+
@person = Person.new
|
|
76
|
+
@person.stub!(
|
|
77
|
+
:in_both_indexes? => false,
|
|
78
|
+
:sphinx_document_id => 1
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@client = Riddle::Client.new
|
|
82
|
+
@client.stub!(:update => true)
|
|
83
|
+
Riddle::Client.stub!(:new => @client)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "shouldn't index if delta indexing is disabled" do
|
|
87
|
+
ThinkingSphinx.deltas_enabled = false
|
|
88
|
+
Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
|
|
89
|
+
@client.should_not_receive(:update)
|
|
90
|
+
|
|
91
|
+
@person.send(:index_delta)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "shouldn't index if index updating is disabled" do
|
|
95
|
+
ThinkingSphinx.updates_enabled = false
|
|
96
|
+
Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
|
|
97
|
+
|
|
98
|
+
@person.send(:index_delta)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "shouldn't index if the environment is 'test'" do
|
|
102
|
+
ThinkingSphinx.deltas_enabled = nil
|
|
103
|
+
ThinkingSphinx::Configuration.stub!(:environment => "test")
|
|
104
|
+
Person.sphinx_indexes.first.delta_object.should_not_receive(:`)
|
|
105
|
+
|
|
106
|
+
@person.send(:index_delta)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "should call indexer for the delta index" do
|
|
110
|
+
Person.sphinx_indexes.first.delta_object.should_receive(:`).with(
|
|
111
|
+
"#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config #{ThinkingSphinx::Configuration.instance.config_file} --rotate person_delta"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
@person.send(:index_delta)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "shouldn't update the deleted attribute if not in the index" do
|
|
118
|
+
@client.should_not_receive(:update)
|
|
119
|
+
|
|
120
|
+
@person.send(:index_delta)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should update the deleted attribute if in the core index" do
|
|
124
|
+
@person.stub!(:in_both_indexes? => true)
|
|
125
|
+
@client.should_receive(:update)
|
|
126
|
+
|
|
127
|
+
@person.send(:index_delta)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|