DrMark-thinking-sphinx 0.9.9 → 1.1.6
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/README +64 -2
- data/lib/thinking_sphinx.rb +88 -11
- data/lib/thinking_sphinx/active_record.rb +136 -21
- data/lib/thinking_sphinx/active_record/delta.rb +43 -62
- data/lib/thinking_sphinx/active_record/has_many_association.rb +1 -1
- data/lib/thinking_sphinx/active_record/search.rb +7 -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 +130 -0
- data/lib/thinking_sphinx/association.rb +17 -0
- data/lib/thinking_sphinx/attribute.rb +171 -97
- data/lib/thinking_sphinx/collection.rb +126 -2
- data/lib/thinking_sphinx/configuration.rb +120 -171
- data/lib/thinking_sphinx/core/string.rb +15 -0
- data/lib/thinking_sphinx/deltas.rb +27 -0
- data/lib/thinking_sphinx/deltas/datetime_delta.rb +50 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +67 -0
- data/lib/thinking_sphinx/deltas/delayed_delta.rb +25 -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/facet.rb +58 -0
- data/lib/thinking_sphinx/facet_collection.rb +60 -0
- data/lib/thinking_sphinx/field.rb +18 -52
- data/lib/thinking_sphinx/index.rb +246 -199
- data/lib/thinking_sphinx/index/builder.rb +85 -16
- data/lib/thinking_sphinx/rails_additions.rb +85 -5
- data/lib/thinking_sphinx/search.rb +459 -190
- data/lib/thinking_sphinx/tasks.rb +128 -0
- data/spec/unit/thinking_sphinx/active_record/delta_spec.rb +53 -124
- data/spec/unit/thinking_sphinx/active_record/has_many_association_spec.rb +2 -2
- data/spec/unit/thinking_sphinx/active_record_spec.rb +110 -30
- data/spec/unit/thinking_sphinx/attribute_spec.rb +16 -149
- data/spec/unit/thinking_sphinx/collection_spec.rb +14 -0
- data/spec/unit/thinking_sphinx/configuration_spec.rb +54 -412
- data/spec/unit/thinking_sphinx/core/string_spec.rb +9 -0
- data/spec/unit/thinking_sphinx/field_spec.rb +0 -79
- data/spec/unit/thinking_sphinx/index/builder_spec.rb +1 -29
- data/spec/unit/thinking_sphinx/index/faux_column_spec.rb +1 -39
- data/spec/unit/thinking_sphinx/index_spec.rb +78 -226
- data/spec/unit/thinking_sphinx/search_spec.rb +29 -228
- data/spec/unit/thinking_sphinx_spec.rb +23 -19
- data/tasks/distribution.rb +48 -0
- data/tasks/rails.rake +1 -0
- data/tasks/testing.rb +86 -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/{lib → vendor/riddle/lib}/riddle.rb +9 -5
- data/{lib → vendor/riddle/lib}/riddle/client.rb +6 -26
- data/{lib → vendor/riddle/lib}/riddle/client/filter.rb +10 -1
- data/{lib → vendor/riddle/lib}/riddle/client/message.rb +0 -0
- data/{lib → vendor/riddle/lib}/riddle/client/response.rb +0 -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 +37 -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 +44 -0
- metadata +63 -10
- data/lib/test.rb +0 -46
- data/tasks/thinking_sphinx_tasks.rake +0 -1
- data/tasks/thinking_sphinx_tasks.rb +0 -86
@@ -1,6 +1,10 @@
|
|
1
1
|
module ThinkingSphinx
|
2
2
|
class Collection < ::Array
|
3
|
-
attr_reader :total_entries, :total_pages, :current_page
|
3
|
+
attr_reader :total_entries, :total_pages, :current_page, :per_page
|
4
|
+
attr_accessor :results
|
5
|
+
|
6
|
+
# Compatibility with older versions of will_paginate
|
7
|
+
alias_method :page_count, :total_pages
|
4
8
|
|
5
9
|
def initialize(page, per_page, entries, total_entries)
|
6
10
|
@current_page, @per_page, @total_entries = page, per_page, total_entries
|
@@ -8,6 +12,94 @@ module ThinkingSphinx
|
|
8
12
|
@total_pages = (entries / @per_page.to_f).ceil
|
9
13
|
end
|
10
14
|
|
15
|
+
def self.ids_from_results(results, page, limit, options)
|
16
|
+
collection = self.new(page, limit,
|
17
|
+
results[:total] || 0, results[:total_found] || 0
|
18
|
+
)
|
19
|
+
collection.results = results
|
20
|
+
collection.replace results[:matches].collect { |match|
|
21
|
+
match[:attributes]["sphinx_internal_id"]
|
22
|
+
}
|
23
|
+
return collection
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.create_from_results(results, page, limit, options)
|
27
|
+
collection = self.new(page, limit,
|
28
|
+
results[:total] || 0, results[:total_found] || 0
|
29
|
+
)
|
30
|
+
collection.results = results
|
31
|
+
collection.replace instances_from_matches(results[:matches], options)
|
32
|
+
return collection
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.instances_from_matches(matches, options = {})
|
36
|
+
if klass = options[:class]
|
37
|
+
instances_from_class klass, matches, options
|
38
|
+
else
|
39
|
+
instances_from_classes matches, options
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.instances_from_class(klass, matches, options = {})
|
44
|
+
index_options = klass.sphinx_index_options
|
45
|
+
|
46
|
+
ids = matches.collect { |match| match[:attributes]["sphinx_internal_id"] }
|
47
|
+
instances = ids.length > 0 ? klass.find(
|
48
|
+
:all,
|
49
|
+
:conditions => {klass.primary_key.to_sym => ids},
|
50
|
+
:include => (options[:include] || index_options[:include]),
|
51
|
+
:select => (options[:select] || index_options[:select]),
|
52
|
+
:order => (options[:sql_order] || index_options[:sql_order])
|
53
|
+
) : []
|
54
|
+
|
55
|
+
# Raise an exception if we find records in Sphinx but not in the DB, so
|
56
|
+
# the search method can retry without them. See
|
57
|
+
# ThinkingSphinx::Search.retry_search_on_stale_index.
|
58
|
+
if options[:raise_on_stale] && instances.length < ids.length
|
59
|
+
stale_ids = ids - instances.map {|i| i.id }
|
60
|
+
raise StaleIdsException, stale_ids
|
61
|
+
end
|
62
|
+
|
63
|
+
# if the user has specified an SQL order, return the collection
|
64
|
+
# without rearranging it into the Sphinx order
|
65
|
+
return instances if options[:sql_order]
|
66
|
+
|
67
|
+
ids.collect { |obj_id|
|
68
|
+
instances.detect { |obj| obj.id == obj_id }
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
# Group results by class and call #find(:all) once for each group to reduce
|
73
|
+
# the number of #find's in multi-model searches.
|
74
|
+
#
|
75
|
+
def self.instances_from_classes(matches, options = {})
|
76
|
+
groups = matches.group_by { |match| match[:attributes]["class_crc"] }
|
77
|
+
groups.each do |crc, group|
|
78
|
+
group.replace(
|
79
|
+
instances_from_class(class_from_crc(crc), group, options)
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
matches.collect do |match|
|
84
|
+
groups.detect { |crc, group|
|
85
|
+
crc == match[:attributes]["class_crc"]
|
86
|
+
}[1].detect { |obj|
|
87
|
+
obj.id == match[:attributes]["sphinx_internal_id"]
|
88
|
+
}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.class_from_crc(crc)
|
93
|
+
@@models_by_crc ||= ThinkingSphinx.indexed_models.inject({}) do |hash, model|
|
94
|
+
hash[model.constantize.to_crc32] = model
|
95
|
+
model.constantize.subclasses.each { |subclass|
|
96
|
+
hash[subclass.to_crc32] = subclass.name
|
97
|
+
}
|
98
|
+
hash
|
99
|
+
end
|
100
|
+
@@models_by_crc[crc].constantize
|
101
|
+
end
|
102
|
+
|
11
103
|
def previous_page
|
12
104
|
current_page > 1 ? (current_page - 1) : nil
|
13
105
|
end
|
@@ -19,5 +111,37 @@ module ThinkingSphinx
|
|
19
111
|
def offset
|
20
112
|
(current_page - 1) * @per_page
|
21
113
|
end
|
114
|
+
|
115
|
+
def method_missing(method, *args, &block)
|
116
|
+
super unless method.to_s[/^each_with_.*/]
|
117
|
+
|
118
|
+
each_with_attribute method.to_s.gsub(/^each_with_/, ''), &block
|
119
|
+
end
|
120
|
+
|
121
|
+
def each_with_groupby_and_count(&block)
|
122
|
+
results[:matches].each_with_index do |match, index|
|
123
|
+
yield self[index], match[:attributes]["@groupby"], match[:attributes]["@count"]
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def each_with_attribute(attribute, &block)
|
128
|
+
results[:matches].each_with_index do |match, index|
|
129
|
+
yield self[index], (match[:attributes][attribute] || match[:attributes]["@#{attribute}"])
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def each_with_weighting(&block)
|
134
|
+
results[:matches].each_with_index do |match, index|
|
135
|
+
yield self[index], match[:weight]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def inject_with_groupby_and_count(initial = nil, &block)
|
140
|
+
index = -1
|
141
|
+
results[:matches].inject(initial) do |memo, match|
|
142
|
+
index += 1
|
143
|
+
yield memo, self[index], match[:attributes]["@groupby"], match[:attributes]["@count"]
|
144
|
+
end
|
145
|
+
end
|
22
146
|
end
|
23
|
-
end
|
147
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'erb'
|
2
|
+
require 'singleton'
|
2
3
|
|
3
4
|
module ThinkingSphinx
|
4
5
|
# This class both keeps track of the configuration settings for Sphinx and
|
@@ -41,49 +42,66 @@ module ThinkingSphinx
|
|
41
42
|
# don't set allow_star to true.
|
42
43
|
#
|
43
44
|
class Configuration
|
45
|
+
include Singleton
|
46
|
+
|
47
|
+
SourceOptions = %w( mysql_connect_flags sql_range_step sql_query_pre
|
48
|
+
sql_query_post sql_ranged_throttle sql_query_post_index )
|
49
|
+
|
50
|
+
IndexOptions = %w( charset_table charset_type docinfo enable_star
|
51
|
+
exceptions html_index_attrs html_remove_elements html_strip ignore_chars
|
52
|
+
min_infix_len min_prefix_len min_word_len mlock morphology ngram_chars
|
53
|
+
ngram_len phrase_boundary phrase_boundary_step preopen stopwords
|
54
|
+
wordforms )
|
55
|
+
|
44
56
|
attr_accessor :config_file, :searchd_log_file, :query_log_file,
|
45
|
-
:pid_file, :searchd_file_path, :address, :port, :
|
46
|
-
:
|
47
|
-
|
48
|
-
|
57
|
+
:pid_file, :searchd_file_path, :address, :port, :allow_star,
|
58
|
+
:database_yml_file, :app_root, :bin_path, :model_directories
|
59
|
+
|
60
|
+
attr_accessor :source_options, :index_options
|
49
61
|
|
50
|
-
attr_reader :environment
|
62
|
+
attr_reader :environment, :configuration
|
51
63
|
|
52
64
|
# Load in the configuration settings - this will look for config/sphinx.yml
|
53
65
|
# and parse it according to the current environment.
|
54
66
|
#
|
55
67
|
def initialize(app_root = Dir.pwd)
|
68
|
+
self.reset
|
69
|
+
end
|
70
|
+
|
71
|
+
def reset
|
56
72
|
self.app_root = RAILS_ROOT if defined?(RAILS_ROOT)
|
57
73
|
self.app_root = Merb.root if defined?(Merb)
|
58
74
|
self.app_root ||= app_root
|
59
75
|
|
76
|
+
@configuration = Riddle::Configuration.new
|
77
|
+
@configuration.searchd.address = "127.0.0.1"
|
78
|
+
@configuration.searchd.port = 3312
|
79
|
+
@configuration.searchd.pid_file = "#{self.app_root}/log/searchd.#{environment}.pid"
|
80
|
+
@configuration.searchd.log = "#{self.app_root}/log/searchd.log"
|
81
|
+
@configuration.searchd.query_log = "#{self.app_root}/log/searchd.query.log"
|
82
|
+
|
60
83
|
self.database_yml_file = "#{self.app_root}/config/database.yml"
|
61
84
|
self.config_file = "#{self.app_root}/config/#{environment}.sphinx.conf"
|
62
|
-
self.searchd_log_file = "#{self.app_root}/log/searchd.log"
|
63
|
-
self.query_log_file = "#{self.app_root}/log/searchd.query.log"
|
64
|
-
self.pid_file = "#{self.app_root}/log/searchd.#{environment}.pid"
|
65
85
|
self.searchd_file_path = "#{self.app_root}/db/sphinx/#{environment}"
|
66
|
-
self.address = "127.0.0.1"
|
67
|
-
self.port = 3312
|
68
86
|
self.allow_star = false
|
69
|
-
self.
|
70
|
-
self.
|
71
|
-
|
72
|
-
self.mem_limit = "64M"
|
73
|
-
self.max_matches = 1000
|
74
|
-
self.morphology = "stem_en"
|
75
|
-
self.charset_type = "utf-8"
|
76
|
-
self.charset_table = nil
|
77
|
-
self.ignore_chars = nil
|
78
|
-
self.html_strip = false
|
79
|
-
self.html_remove_elements = ""
|
87
|
+
self.bin_path = ""
|
88
|
+
self.model_directories = ["#{app_root}/app/models/"] +
|
89
|
+
Dir.glob("#{app_root}/vendor/plugins/*/app/models/")
|
80
90
|
|
91
|
+
self.source_options = {}
|
92
|
+
self.index_options = {
|
93
|
+
:charset_type => "utf-8",
|
94
|
+
:morphology => "stem_en"
|
95
|
+
}
|
96
|
+
|
81
97
|
parse_config
|
98
|
+
|
99
|
+
self
|
82
100
|
end
|
83
101
|
|
84
102
|
def self.environment
|
85
103
|
@@environment ||= (
|
86
|
-
defined?(Merb) ?
|
104
|
+
defined?(Merb) ? Merb.environment : ENV['RAILS_ENV']
|
87
105
|
) || "development"
|
88
106
|
end
|
89
107
|
|
@@ -91,64 +109,26 @@ module ThinkingSphinx
|
|
91
109
|
self.class.environment
|
92
110
|
end
|
93
111
|
|
112
|
+
def controller
|
113
|
+
@controller ||= Riddle::Controller.new(@configuration, self.config_file)
|
114
|
+
end
|
115
|
+
|
94
116
|
# Generate the config file for Sphinx by using all the settings defined and
|
95
117
|
# looping through all the models with indexes to build the relevant
|
96
118
|
# indexer and searchd configuration, and sources and indexes details.
|
97
119
|
#
|
98
120
|
def build(file_path=nil)
|
121
|
+
load_models
|
99
122
|
file_path ||= "#{self.config_file}"
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
123
|
+
|
124
|
+
@configuration.indexes.clear
|
125
|
+
|
126
|
+
ThinkingSphinx.indexed_models.each_with_index do |model, model_index|
|
127
|
+
@configuration.indexes.concat model.constantize.to_riddle(model_index)
|
128
|
+
end
|
104
129
|
|
105
130
|
open(file_path, "w") do |file|
|
106
|
-
file.write
|
107
|
-
indexer
|
108
|
-
{
|
109
|
-
mem_limit = #{self.mem_limit}
|
110
|
-
}
|
111
|
-
|
112
|
-
searchd
|
113
|
-
{
|
114
|
-
address = #{self.address}
|
115
|
-
port = #{self.port}
|
116
|
-
log = #{self.searchd_log_file}
|
117
|
-
query_log = #{self.query_log_file}
|
118
|
-
read_timeout = 5
|
119
|
-
max_children = 30
|
120
|
-
pid_file = #{self.pid_file}
|
121
|
-
max_matches = #{self.max_matches}
|
122
|
-
}
|
123
|
-
CONFIG
|
124
|
-
|
125
|
-
ThinkingSphinx.indexed_models.each_with_index do |model, model_index|
|
126
|
-
model = model.constantize
|
127
|
-
sources = []
|
128
|
-
delta_sources = []
|
129
|
-
prefixed_fields = []
|
130
|
-
infixed_fields = []
|
131
|
-
|
132
|
-
model.indexes.select { |index| index.model == model }.each_with_index do |index, i|
|
133
|
-
file.write index.to_config(model, i, database_conf, charset_type, model_index)
|
134
|
-
|
135
|
-
create_array_accum if index.adapter == :postgres
|
136
|
-
sources << "#{ThinkingSphinx::Index.name(model)}_#{i}_core"
|
137
|
-
delta_sources << "#{ThinkingSphinx::Index.name(model)}_#{i}_delta" if index.delta?
|
138
|
-
end
|
139
|
-
|
140
|
-
next if sources.empty?
|
141
|
-
|
142
|
-
source_list = sources.collect { |s| "source = #{s}" }.join("\n")
|
143
|
-
delta_list = delta_sources.collect { |s| "source = #{s}" }.join("\n")
|
144
|
-
|
145
|
-
file.write core_index_for_model(model, source_list)
|
146
|
-
unless delta_list.blank?
|
147
|
-
file.write delta_index_for_model(model, delta_list)
|
148
|
-
end
|
149
|
-
|
150
|
-
file.write distributed_index_for_model(model)
|
151
|
-
end
|
131
|
+
file.write @configuration.render
|
152
132
|
end
|
153
133
|
end
|
154
134
|
|
@@ -157,25 +137,66 @@ searchd
|
|
157
137
|
# messy dependencies issues).
|
158
138
|
#
|
159
139
|
def load_models
|
160
|
-
|
161
|
-
|
162
|
-
|
140
|
+
self.model_directories.each do |base|
|
141
|
+
Dir["#{base}**/*.rb"].each do |file|
|
142
|
+
model_name = file.gsub(/^#{base}([\w_\/\\]+)\.rb/, '\1')
|
163
143
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
144
|
+
next if model_name.nil?
|
145
|
+
next if ::ActiveRecord::Base.send(:subclasses).detect { |model|
|
146
|
+
model.name == model_name
|
147
|
+
}
|
168
148
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
149
|
+
begin
|
150
|
+
model_name.camelize.constantize
|
151
|
+
rescue LoadError
|
152
|
+
model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
|
153
|
+
rescue NameError
|
154
|
+
next
|
155
|
+
end
|
175
156
|
end
|
176
157
|
end
|
177
158
|
end
|
178
159
|
|
160
|
+
def address
|
161
|
+
@configuration.searchd.address
|
162
|
+
end
|
163
|
+
|
164
|
+
def address=(address)
|
165
|
+
@configuration.searchd.address = address
|
166
|
+
end
|
167
|
+
|
168
|
+
def port
|
169
|
+
@configuration.searchd.port
|
170
|
+
end
|
171
|
+
|
172
|
+
def port=(port)
|
173
|
+
@configuration.searchd.port = port
|
174
|
+
end
|
175
|
+
|
176
|
+
def pid_file
|
177
|
+
@configuration.searchd.pid_file
|
178
|
+
end
|
179
|
+
|
180
|
+
def pid_file=(pid_file)
|
181
|
+
@configuration.searchd.pid_file = pid_file
|
182
|
+
end
|
183
|
+
|
184
|
+
def searchd_log_file
|
185
|
+
@configuration.searchd.log
|
186
|
+
end
|
187
|
+
|
188
|
+
def searchd_log_file=(file)
|
189
|
+
@configuration.searchd.log = file
|
190
|
+
end
|
191
|
+
|
192
|
+
def query_log_file
|
193
|
+
@configuration.searchd.query_log
|
194
|
+
end
|
195
|
+
|
196
|
+
def query_log_file=(file)
|
197
|
+
@configuration.searchd.query_log = file
|
198
|
+
end
|
199
|
+
|
179
200
|
private
|
180
201
|
|
181
202
|
# Parse the config/sphinx.yml file - if it exists - then use the attribute
|
@@ -189,100 +210,28 @@ searchd
|
|
189
210
|
|
190
211
|
conf.each do |key,value|
|
191
212
|
self.send("#{key}=", value) if self.methods.include?("#{key}=")
|
213
|
+
|
214
|
+
set_sphinx_setting self.source_options, key, value, SourceOptions
|
215
|
+
set_sphinx_setting self.index_options, key, value, IndexOptions
|
216
|
+
set_sphinx_setting @configuration.searchd, key, value
|
217
|
+
set_sphinx_setting @configuration.indexer, key, value
|
192
218
|
end unless conf.nil?
|
193
|
-
end
|
194
|
-
|
195
|
-
def core_index_for_model(model, sources)
|
196
|
-
output = <<-INDEX
|
197
|
-
|
198
|
-
index #{ThinkingSphinx::Index.name(model)}_core
|
199
|
-
{
|
200
|
-
#{sources}
|
201
|
-
path = #{self.searchd_file_path}/#{ThinkingSphinx::Index.name(model)}_core
|
202
|
-
charset_type = #{self.charset_type}
|
203
|
-
INDEX
|
204
219
|
|
205
|
-
|
206
|
-
index.options[:morphology] || morph
|
207
|
-
}
|
208
|
-
output += " morphology = #{morphology}\n" unless morphology.blank?
|
209
|
-
output += " charset_table = #{self.charset_table}\n" unless self.charset_table.nil?
|
210
|
-
output += " ignore_chars = #{self.ignore_chars}\n" unless self.ignore_chars.nil?
|
220
|
+
self.bin_path += '/' unless self.bin_path.blank?
|
211
221
|
|
212
222
|
if self.allow_star
|
213
|
-
|
214
|
-
|
215
|
-
output += " min_prefix_len = #{self.min_prefix_len}\n"
|
216
|
-
else
|
217
|
-
# New, better way of turning on enable_star - thanks to James Healy
|
218
|
-
output += " enable_star = 1\n" if self.enable_star
|
219
|
-
output += " min_prefix_len = #{self.min_prefix_len}\n" unless self.min_prefix_len.nil?
|
220
|
-
output += " min_infix_len = #{self.min_infix_len}\n" unless self.min_infix_len.nil?
|
223
|
+
self.index_options[:enable_star] = true
|
224
|
+
self.index_options[:min_prefix_len] = 1
|
221
225
|
end
|
222
|
-
|
223
|
-
|
224
|
-
output += " html_strip = 1\n" if self.html_strip
|
225
|
-
output += " html_remove_elements = #{self.html_remove_elements}\n" unless self.html_remove_elements.blank?
|
226
|
-
|
227
|
-
unless model.indexes.collect(&:prefix_fields).flatten.empty?
|
228
|
-
output += " prefix_fields = #{model.indexes.collect(&:prefix_fields).flatten.map(&:unique_name).join(', ')}\n"
|
229
|
-
else
|
230
|
-
output += " prefix_fields = _\n" unless model.indexes.collect(&:infix_fields).flatten.empty?
|
231
|
-
end
|
232
|
-
|
233
|
-
unless model.indexes.collect(&:infix_fields).flatten.empty?
|
234
|
-
output += " infix_fields = #{model.indexes.collect(&:infix_fields).flatten.map(&:unique_name).join(', ')}\n"
|
235
|
-
else
|
236
|
-
output += " infix_fields = -\n" unless model.indexes.collect(&:prefix_fields).flatten.empty?
|
237
|
-
end
|
238
|
-
|
239
|
-
output + "}\n"
|
240
|
-
end
|
241
|
-
|
242
|
-
def delta_index_for_model(model, sources)
|
243
|
-
<<-INDEX
|
244
|
-
index #{ThinkingSphinx::Index.name(model)}_delta : #{ThinkingSphinx::Index.name(model)}_core
|
245
|
-
{
|
246
|
-
#{sources}
|
247
|
-
path = #{self.searchd_file_path}/#{ThinkingSphinx::Index.name(model)}_delta
|
248
|
-
}
|
249
|
-
INDEX
|
250
|
-
end
|
251
|
-
|
252
|
-
def distributed_index_for_model(model)
|
253
|
-
sources = ["local = #{ThinkingSphinx::Index.name(model)}_core"]
|
254
|
-
if model.indexes.any? { |index| index.delta? }
|
255
|
-
sources << "local = #{ThinkingSphinx::Index.name(model)}_delta"
|
256
|
-
end
|
257
|
-
|
258
|
-
<<-INDEX
|
259
|
-
index #{ThinkingSphinx::Index.name(model)}
|
260
|
-
{
|
261
|
-
type = distributed
|
262
|
-
#{ sources.join("\n ") }
|
263
|
-
charset_type = #{self.charset_type}
|
264
|
-
}
|
265
|
-
INDEX
|
266
226
|
end
|
267
227
|
|
268
|
-
def
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
(
|
275
|
-
sfunc = array_append,
|
276
|
-
stype = anyarray,
|
277
|
-
initcond = '{}'
|
278
|
-
);
|
279
|
-
SQL
|
280
|
-
rescue
|
281
|
-
raise unless $!.to_s =~ /already exists with same argument types/
|
282
|
-
::ActiveRecord::Base.connection.execute "rollback to savepoint ts"
|
228
|
+
def set_sphinx_setting(object, key, value, allowed = {})
|
229
|
+
if object.is_a?(Hash)
|
230
|
+
object[key.to_sym] = value if allowed.include?(key.to_s)
|
231
|
+
else
|
232
|
+
object.send("#{key}=", value) if object.methods.include?("#{key}")
|
233
|
+
send("#{key}=", value) if self.methods.include?("#{key}")
|
283
234
|
end
|
284
|
-
::ActiveRecord::Base.connection.execute "release savepoint ts"
|
285
|
-
::ActiveRecord::Base.connection.execute "commit"
|
286
235
|
end
|
287
236
|
end
|
288
237
|
end
|