thorsson_thinking-sphinx 1.3.18 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +5 -0
- data/VERSION +1 -1
- data/features/facets.feature +9 -1
- data/features/searching_across_models.feature +1 -1
- data/features/sphinx_scopes.feature +26 -0
- data/features/step_definitions/scope_steps.rb +4 -0
- data/features/thinking_sphinx/models/alpha.rb +1 -0
- data/lib/cucumber/thinking_sphinx/external_world.rb +8 -4
- data/lib/thinking_sphinx.rb +1 -0
- data/lib/thinking_sphinx/active_record.rb +4 -0
- data/lib/thinking_sphinx/active_record/scopes.rb +7 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +2 -1
- data/lib/thinking_sphinx/auto_version.rb +2 -0
- data/lib/thinking_sphinx/bundled_search.rb +44 -0
- data/lib/thinking_sphinx/class_facet.rb +3 -2
- data/lib/thinking_sphinx/configuration.rb +8 -7
- data/lib/thinking_sphinx/context.rb +4 -2
- data/lib/thinking_sphinx/deltas/default_delta.rb +1 -1
- data/lib/thinking_sphinx/facet.rb +6 -5
- data/lib/thinking_sphinx/facet_search.rb +51 -23
- data/lib/thinking_sphinx/search.rb +75 -32
- data/lib/thinking_sphinx/tasks.rb +6 -1
- data/spec/thinking_sphinx/active_record/delta_spec.rb +1 -1
- data/spec/thinking_sphinx/active_record/scopes_spec.rb +2 -3
- data/spec/thinking_sphinx/auto_version_spec.rb +8 -0
- data/spec/thinking_sphinx/context_spec.rb +3 -2
- data/spec/thinking_sphinx/facet_search_spec.rb +75 -81
- data/spec/thinking_sphinx/facet_spec.rb +4 -4
- data/spec/thinking_sphinx/search_methods_spec.rb +4 -0
- data/spec/thinking_sphinx/search_spec.rb +26 -8
- data/spec/thinking_sphinx/test_spec.rb +20 -0
- data/tasks/distribution.rb +4 -2
- metadata +53 -45
- data/features/thinking_sphinx/database.yml +0 -3
data/README.textile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.20
|
data/features/facets.feature
CHANGED
@@ -27,7 +27,7 @@ Feature: Search and browse models by their defined facets
|
|
27
27
|
And I should have the facet State
|
28
28
|
And I should have the facet Age
|
29
29
|
|
30
|
-
Scenario:
|
30
|
+
Scenario: Requesting float facets
|
31
31
|
Given Sphinx is running
|
32
32
|
And I am searching on alphas
|
33
33
|
When I am requesting facet results
|
@@ -80,3 +80,11 @@ Feature: Search and browse models by their defined facets
|
|
80
80
|
And I am searching on posts
|
81
81
|
When I am requesting facet results
|
82
82
|
Then the Comment Ids facet should have 9 keys
|
83
|
+
|
84
|
+
Scenario: Requesting facets from a subclass
|
85
|
+
Given Sphinx is running
|
86
|
+
And I am searching on animals
|
87
|
+
When I am requesting facet results
|
88
|
+
And I want classes included
|
89
|
+
Then I should have the facet Class
|
90
|
+
|
@@ -7,7 +7,7 @@ Feature: Searching across multiple model
|
|
7
7
|
Given Sphinx is running
|
8
8
|
When I search for James
|
9
9
|
And I am retrieving the result count
|
10
|
-
Then I should get a value of
|
10
|
+
Then I should get a value of 6
|
11
11
|
|
12
12
|
Scenario: Confirming existance of a document id in a given index
|
13
13
|
Given Sphinx is running
|
@@ -40,3 +40,29 @@ Feature: Sphinx Scopes
|
|
40
40
|
When I use the with_first_name scope set to "Andrew"
|
41
41
|
And I am retrieving the scoped result count
|
42
42
|
Then I should get a value of 7
|
43
|
+
|
44
|
+
Scenario: Counts with scopes and additional query terms
|
45
|
+
Given Sphinx is running
|
46
|
+
And I am searching on people
|
47
|
+
When I use the with_first_name scope set to "Andrew"
|
48
|
+
And I am retrieving the scoped result count for "Byrne"
|
49
|
+
Then I should get a value of 1
|
50
|
+
|
51
|
+
Scenario: Default Scope
|
52
|
+
Given Sphinx is running
|
53
|
+
And I am searching on andrews
|
54
|
+
Then I should get 7 results
|
55
|
+
|
56
|
+
Scenario: Default Scope and additional query terms
|
57
|
+
Given Sphinx is running
|
58
|
+
And I am searching on andrews
|
59
|
+
When I search for "Byrne"
|
60
|
+
Then I should get 1 result
|
61
|
+
|
62
|
+
Scenario: Explicit scope plus search over a default scope
|
63
|
+
Given Sphinx is running
|
64
|
+
And I am searching on andrews
|
65
|
+
When I use the locked_last_name scope
|
66
|
+
And I search for "Cecil"
|
67
|
+
Then I should get 1 result
|
68
|
+
|
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'thinking_sphinx/test'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
7
11
|
end
|
8
12
|
end
|
data/lib/thinking_sphinx.rb
CHANGED
@@ -10,6 +10,7 @@ require 'thinking_sphinx/property'
|
|
10
10
|
require 'thinking_sphinx/active_record'
|
11
11
|
require 'thinking_sphinx/association'
|
12
12
|
require 'thinking_sphinx/attribute'
|
13
|
+
require 'thinking_sphinx/bundled_search'
|
13
14
|
require 'thinking_sphinx/configuration'
|
14
15
|
require 'thinking_sphinx/context'
|
15
16
|
require 'thinking_sphinx/excerpter'
|
@@ -322,6 +322,10 @@ module ThinkingSphinx
|
|
322
322
|
end
|
323
323
|
end
|
324
324
|
|
325
|
+
attr_accessor :excerpts
|
326
|
+
attr_accessor :sphinx_attributes
|
327
|
+
attr_accessor :matching_fields
|
328
|
+
|
325
329
|
def in_index?(suffix)
|
326
330
|
self.class.search_for_id self.sphinx_document_id, sphinx_index_name(suffix)
|
327
331
|
end
|
@@ -53,6 +53,13 @@ module ThinkingSphinx
|
|
53
53
|
|
54
54
|
ThinkingSphinx::Search.new(options)
|
55
55
|
end
|
56
|
+
|
57
|
+
define_method("#{method}_without_default".to_sym) do |*args|
|
58
|
+
options = {:classes => classes_option, :ignore_default => true}
|
59
|
+
options.merge! block.call(*args)
|
60
|
+
|
61
|
+
ThinkingSphinx::Search.new(options)
|
62
|
+
end
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
@@ -13,7 +13,8 @@ module ThinkingSphinx
|
|
13
13
|
case model.connection.class.name
|
14
14
|
when "ActiveRecord::ConnectionAdapters::MysqlAdapter",
|
15
15
|
"ActiveRecord::ConnectionAdapters::MysqlplusAdapter",
|
16
|
-
"ActiveRecord::ConnectionAdapters::Mysql2Adapter"
|
16
|
+
"ActiveRecord::ConnectionAdapters::Mysql2Adapter",
|
17
|
+
"ActiveRecord::ConnectionAdapters::NullDBAdapter"
|
17
18
|
ThinkingSphinx::MysqlAdapter.new model
|
18
19
|
when "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter"
|
19
20
|
ThinkingSphinx::PostgreSQLAdapter.new model
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ThinkingSphinx
|
2
|
+
class BundledSearch
|
3
|
+
attr_reader :client
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@searches = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def search(*args)
|
10
|
+
@searches << ThinkingSphinx.search(*args)
|
11
|
+
@searches.last.append_to client
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_for_ids(*args)
|
15
|
+
@searches << ThinkingSphinx.search_for_ids(*args)
|
16
|
+
@searches.last.append_to client
|
17
|
+
end
|
18
|
+
|
19
|
+
def searches
|
20
|
+
populate
|
21
|
+
@searches
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def client
|
27
|
+
@client ||= ThinkingSphinx::Configuration.instance.client
|
28
|
+
end
|
29
|
+
|
30
|
+
def populated?
|
31
|
+
@populated
|
32
|
+
end
|
33
|
+
|
34
|
+
def populate
|
35
|
+
return if populated?
|
36
|
+
|
37
|
+
@populated = true
|
38
|
+
|
39
|
+
client.run.each_with_index do |results, index|
|
40
|
+
searches[index].populate_from_queue results
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -8,8 +8,9 @@ module ThinkingSphinx
|
|
8
8
|
"class_crc"
|
9
9
|
end
|
10
10
|
|
11
|
-
def value(object,
|
12
|
-
|
11
|
+
def value(object, attribute_hash)
|
12
|
+
crc = attribute_hash['class_crc']
|
13
|
+
ThinkingSphinx::Configuration.instance.models_by_crc[crc]
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
@@ -54,13 +54,14 @@ module ThinkingSphinx
|
|
54
54
|
sql_query_killlist sql_ranged_throttle sql_query_post_index unpack_zlib
|
55
55
|
unpack_mysqlcompress unpack_mysqlcompress_maxsize )
|
56
56
|
|
57
|
-
IndexOptions = %w( charset_table charset_type charset_dictpath
|
58
|
-
enable_star exceptions
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
IndexOptions = %w( blend_chars charset_table charset_type charset_dictpath
|
58
|
+
docinfo enable_star exceptions expand_keywords hitless_words
|
59
|
+
html_index_attrs html_remove_elements html_strip index_exact_words
|
60
|
+
ignore_chars inplace_docinfo_gap inplace_enable inplace_hit_gap
|
61
|
+
inplace_reloc_factor inplace_write_factor min_infix_len min_prefix_len
|
62
|
+
min_stemming_len min_word_len mlock morphology ngram_chars ngram_len
|
63
|
+
ondisk_dict overshort_step phrase_boundary phrase_boundary_step preopen
|
64
|
+
stopwords stopwords_step wordforms )
|
64
65
|
|
65
66
|
CustomOptions = %w( disable_range )
|
66
67
|
|
@@ -65,8 +65,10 @@ class ThinkingSphinx::Context
|
|
65
65
|
model_name.gsub!(/.*[\/\\]/, '').nil? ? next : retry
|
66
66
|
rescue NameError
|
67
67
|
next
|
68
|
-
rescue StandardError
|
69
|
-
STDERR.puts "Warning: Error loading #{file}"
|
68
|
+
rescue StandardError => err
|
69
|
+
STDERR.puts "Warning: Error loading #{file}:"
|
70
|
+
STDERR.puts err.message
|
71
|
+
STDERR.puts err.backtrace.join("\n"), ''
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|
@@ -44,7 +44,7 @@ module ThinkingSphinx
|
|
44
44
|
config = ThinkingSphinx::Configuration.instance
|
45
45
|
rotate = ThinkingSphinx.sphinx_running? ? "--rotate" : ""
|
46
46
|
|
47
|
-
output = `#{config.bin_path}#{config.indexer_binary_name} --config
|
47
|
+
output = `#{config.bin_path}#{config.indexer_binary_name} --config "#{config.config_file}" #{rotate} #{model.delta_index_names.join(' ')}`
|
48
48
|
puts(output) unless ThinkingSphinx.suppress_delta_output?
|
49
49
|
end
|
50
50
|
|
@@ -71,7 +71,12 @@ module ThinkingSphinx
|
|
71
71
|
@property.is_a?(Field) ? :string : @property.type
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
74
|
+
def float?
|
75
|
+
@property.type == :float
|
76
|
+
end
|
77
|
+
|
78
|
+
def value(object, attribute_hash)
|
79
|
+
attribute_value = attribute_hash['@groupby']
|
75
80
|
return translate(object, attribute_value) if translate? || float?
|
76
81
|
|
77
82
|
case @property.type
|
@@ -117,9 +122,5 @@ module ThinkingSphinx
|
|
117
122
|
def column
|
118
123
|
@property.columns.first
|
119
124
|
end
|
120
|
-
|
121
|
-
def float?
|
122
|
-
@property.type == :float
|
123
|
-
end
|
124
125
|
end
|
125
126
|
end
|
@@ -44,23 +44,21 @@ module ThinkingSphinx
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def populate
|
47
|
-
facet_names
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
47
|
+
ThinkingSphinx::Search.bundle_searches(facet_names) { |sphinx, name|
|
48
|
+
sphinx.search *(args + [facet_search_options(name)])
|
49
|
+
}.each_with_index { |search, index|
|
50
|
+
add_from_results facet_names[index], search
|
51
|
+
}
|
53
52
|
end
|
54
53
|
|
55
|
-
def facet_search_options
|
56
|
-
config = ThinkingSphinx::Configuration.instance
|
57
|
-
max = config.configuration.searchd.max_matches || 1000
|
58
|
-
|
54
|
+
def facet_search_options(facet_name)
|
59
55
|
options.merge(
|
60
56
|
:group_function => :attr,
|
61
|
-
:limit =>
|
62
|
-
:max_matches =>
|
63
|
-
:page => 1
|
57
|
+
:limit => max_matches,
|
58
|
+
:max_matches => max_matches,
|
59
|
+
:page => 1,
|
60
|
+
:group_by => facet_name,
|
61
|
+
:ids_only => !translate?(facet_name)
|
64
62
|
)
|
65
63
|
end
|
66
64
|
|
@@ -101,21 +99,34 @@ module ThinkingSphinx
|
|
101
99
|
}
|
102
100
|
end
|
103
101
|
|
104
|
-
def
|
105
|
-
|
102
|
+
def translate?(name)
|
103
|
+
facet = facet_from_name(name)
|
104
|
+
facet.translate? || facet.float?
|
105
|
+
end
|
106
|
+
|
107
|
+
def config
|
108
|
+
ThinkingSphinx::Configuration.instance
|
109
|
+
end
|
110
|
+
|
111
|
+
def max_matches
|
112
|
+
@max_matches ||= config.configuration.searchd.max_matches || 1000
|
113
|
+
end
|
114
|
+
|
115
|
+
# example: facet = country_facet; name = :country
|
116
|
+
def add_from_results(facet, search)
|
117
|
+
name = ThinkingSphinx::Facet.name_for(facet)
|
118
|
+
facet = facet_from_name(facet)
|
106
119
|
|
107
120
|
self[name] ||= {}
|
108
121
|
|
109
|
-
return if
|
110
|
-
|
111
|
-
facet = facet_from_object(results.first, facet) if facet.is_a?(String)
|
122
|
+
return if search.empty?
|
112
123
|
|
113
|
-
|
114
|
-
facet_value = facet.value(result,
|
124
|
+
search.each_with_match do |result, match|
|
125
|
+
facet_value = facet.value(result, match[:attributes])
|
115
126
|
|
116
127
|
self[name][facet_value] ||= 0
|
117
|
-
self[name][facet_value] += count
|
118
|
-
|
128
|
+
self[name][facet_value] += match[:attributes]["@count"]
|
129
|
+
end
|
119
130
|
end
|
120
131
|
|
121
132
|
def underlying_value(key, value)
|
@@ -130,7 +141,24 @@ module ThinkingSphinx
|
|
130
141
|
end
|
131
142
|
|
132
143
|
def facet_from_object(object, name)
|
133
|
-
|
144
|
+
facet = nil
|
145
|
+
klass = object.class
|
146
|
+
|
147
|
+
while klass != ::ActiveRecord::Base && facet.nil?
|
148
|
+
facet = klass.sphinx_facets.detect { |facet|
|
149
|
+
facet.attribute_name == name
|
150
|
+
}
|
151
|
+
klass = klass.superclass
|
152
|
+
end
|
153
|
+
|
154
|
+
facet
|
155
|
+
end
|
156
|
+
|
157
|
+
def facet_from_name(name)
|
158
|
+
name = ThinkingSphinx::Facet.name_for(name)
|
159
|
+
all_facets.detect { |facet|
|
160
|
+
facet.name == name
|
161
|
+
}
|
134
162
|
end
|
135
163
|
end
|
136
164
|
end
|
@@ -57,6 +57,18 @@ module ThinkingSphinx
|
|
57
57
|
ThinkingSphinx.facets *args
|
58
58
|
end
|
59
59
|
|
60
|
+
def self.bundle_searches(enum = nil)
|
61
|
+
bundle = ThinkingSphinx::BundledSearch.new
|
62
|
+
|
63
|
+
if enum.nil?
|
64
|
+
yield bundle
|
65
|
+
else
|
66
|
+
enum.each { |item| yield bundle, item }
|
67
|
+
end
|
68
|
+
|
69
|
+
bundle.searches
|
70
|
+
end
|
71
|
+
|
60
72
|
def self.matching_fields(fields, bitmask)
|
61
73
|
matches = []
|
62
74
|
bitstring = bitmask.to_s(2).rjust(32, '0').reverse
|
@@ -74,6 +86,8 @@ module ThinkingSphinx
|
|
74
86
|
@options = args.extract_options!
|
75
87
|
@args = args
|
76
88
|
|
89
|
+
add_default_scope unless options[:ignore_default]
|
90
|
+
|
77
91
|
populate if @options[:populate]
|
78
92
|
end
|
79
93
|
|
@@ -111,6 +125,7 @@ module ThinkingSphinx
|
|
111
125
|
add_scope(method, *args, &block)
|
112
126
|
return self
|
113
127
|
elsif method == :search_count
|
128
|
+
merge_search one_class.search(*args)
|
114
129
|
return scoped_count
|
115
130
|
elsif method.to_s[/^each_with_.*/].nil? && !@array.respond_to?(method)
|
116
131
|
super
|
@@ -186,6 +201,17 @@ module ThinkingSphinx
|
|
186
201
|
# Compatibility with older versions of will_paginate
|
187
202
|
alias_method :page_count, :total_pages
|
188
203
|
|
204
|
+
# Query time taken
|
205
|
+
#
|
206
|
+
# @return [Integer]
|
207
|
+
#
|
208
|
+
def query_time
|
209
|
+
populate
|
210
|
+
return 0 if @results[:time].nil?
|
211
|
+
|
212
|
+
@query_time ||= @results[:time]
|
213
|
+
end
|
214
|
+
|
189
215
|
# The total number of search results available.
|
190
216
|
#
|
191
217
|
# @return [Integer]
|
@@ -232,6 +258,13 @@ module ThinkingSphinx
|
|
232
258
|
end
|
233
259
|
end
|
234
260
|
|
261
|
+
def each_with_match(&block)
|
262
|
+
populate
|
263
|
+
results[:matches].each_with_index do |match, index|
|
264
|
+
yield self[index], match
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
235
268
|
def excerpt_for(string, model = nil)
|
236
269
|
if model.nil? && one_class
|
237
270
|
model ||= one_class
|
@@ -241,16 +274,45 @@ module ThinkingSphinx
|
|
241
274
|
client.excerpts(
|
242
275
|
:docs => [string],
|
243
276
|
:words => results[:words].keys.join(' '),
|
244
|
-
:index => "#{model.source_of_sphinx_index.sphinx_name}_core"
|
277
|
+
:index => options[:index] || "#{model.source_of_sphinx_index.sphinx_name}_core"
|
245
278
|
).first
|
246
279
|
end
|
247
280
|
|
248
281
|
def search(*args)
|
249
|
-
|
282
|
+
args << args.extract_options!.merge(:ignore_default => true)
|
250
283
|
merge_search ThinkingSphinx::Search.new(*args)
|
251
284
|
self
|
252
285
|
end
|
253
286
|
|
287
|
+
def client
|
288
|
+
client = options[:client] || config.client
|
289
|
+
|
290
|
+
prepare client
|
291
|
+
end
|
292
|
+
|
293
|
+
def append_to(client)
|
294
|
+
prepare client
|
295
|
+
client.append_query query, indexes, comment
|
296
|
+
client.reset
|
297
|
+
end
|
298
|
+
|
299
|
+
def populate_from_queue(results)
|
300
|
+
return if @populated
|
301
|
+
@populated = true
|
302
|
+
@results = results
|
303
|
+
|
304
|
+
if options[:ids_only]
|
305
|
+
replace @results[:matches].collect { |match|
|
306
|
+
match[:attributes]["sphinx_internal_id"]
|
307
|
+
}
|
308
|
+
else
|
309
|
+
replace instances_from_matches
|
310
|
+
add_excerpter
|
311
|
+
add_sphinx_attributes
|
312
|
+
add_matching_fields if client.rank_mode == :fieldmask
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
254
316
|
private
|
255
317
|
|
256
318
|
def config
|
@@ -289,43 +351,32 @@ module ThinkingSphinx
|
|
289
351
|
|
290
352
|
def add_excerpter
|
291
353
|
each do |object|
|
292
|
-
next if object.
|
354
|
+
next if object.nil?
|
293
355
|
|
294
|
-
|
295
|
-
block = lambda { excerpter }
|
296
|
-
|
297
|
-
object.singleton_class.instance_eval do
|
298
|
-
define_method(:excerpts, &block)
|
299
|
-
end
|
356
|
+
object.excerpts = ThinkingSphinx::Excerpter.new self, object
|
300
357
|
end
|
301
358
|
end
|
302
359
|
|
303
360
|
def add_sphinx_attributes
|
304
361
|
each do |object|
|
305
|
-
next if object.nil?
|
362
|
+
next if object.nil?
|
306
363
|
|
307
364
|
match = match_hash object
|
308
365
|
next if match.nil?
|
309
366
|
|
310
|
-
object.
|
311
|
-
define_method(:sphinx_attributes) { match[:attributes] }
|
312
|
-
end
|
367
|
+
object.sphinx_attributes = match[:attributes]
|
313
368
|
end
|
314
369
|
end
|
315
370
|
|
316
371
|
def add_matching_fields
|
317
372
|
each do |object|
|
318
|
-
next if object.nil?
|
373
|
+
next if object.nil?
|
319
374
|
|
320
375
|
match = match_hash object
|
321
376
|
next if match.nil?
|
322
|
-
|
377
|
+
object.matching_fields = ThinkingSphinx::Search.matching_fields(
|
323
378
|
@results[:fields], match[:weight]
|
324
379
|
)
|
325
|
-
|
326
|
-
object.singleton_class.instance_eval do
|
327
|
-
define_method(:matching_fields) { fields }
|
328
|
-
end
|
329
380
|
end
|
330
381
|
end
|
331
382
|
|
@@ -349,9 +400,7 @@ module ThinkingSphinx
|
|
349
400
|
self.class.log(*args)
|
350
401
|
end
|
351
402
|
|
352
|
-
def client
|
353
|
-
client = config.client
|
354
|
-
|
403
|
+
def prepare(client)
|
355
404
|
index_options = one_class ?
|
356
405
|
one_class.sphinx_indexes.first.local_options : {}
|
357
406
|
|
@@ -588,14 +637,6 @@ MSG
|
|
588
637
|
end
|
589
638
|
|
590
639
|
# When passed a Time instance, returns the integer timestamp.
|
591
|
-
#
|
592
|
-
# If using Rails 2.1+, need to handle timezones to translate them back to
|
593
|
-
# UTC, as that's what datetimes will be stored as by MySQL.
|
594
|
-
#
|
595
|
-
# in_time_zone is a method that was added for the timezone support in
|
596
|
-
# Rails 2.1, which is why it's used for testing. I'm sure there's better
|
597
|
-
# ways, but this does the job.
|
598
|
-
#
|
599
640
|
def filter_value(value)
|
600
641
|
case value
|
601
642
|
when Range
|
@@ -603,7 +644,7 @@ MSG
|
|
603
644
|
when Array
|
604
645
|
value.collect { |v| filter_value(v) }.flatten
|
605
646
|
when Time
|
606
|
-
|
647
|
+
[value.to_i]
|
607
648
|
when NilClass
|
608
649
|
0
|
609
650
|
else
|
@@ -747,10 +788,12 @@ MSG
|
|
747
788
|
|
748
789
|
# Adds the default_sphinx_scope if set.
|
749
790
|
def add_default_scope
|
750
|
-
|
791
|
+
return unless one_class && one_class.has_default_sphinx_scope?
|
792
|
+
add_scope(one_class.get_default_sphinx_scope.to_sym)
|
751
793
|
end
|
752
794
|
|
753
795
|
def add_scope(method, *args, &block)
|
796
|
+
method = "#{method}_without_default".to_sym
|
754
797
|
merge_search one_class.send(method, *args, &block)
|
755
798
|
end
|
756
799
|
|
@@ -4,7 +4,12 @@ namespace :thinking_sphinx do
|
|
4
4
|
task :app_env do
|
5
5
|
if defined?(RAILS_ROOT)
|
6
6
|
Rake::Task[:environment].invoke
|
7
|
-
|
7
|
+
|
8
|
+
if defined?(Rails.configuration)
|
9
|
+
Rails.configuration.cache_classes = false
|
10
|
+
else
|
11
|
+
Rails::Initializer.run { |config| config.cache_classes = false }
|
12
|
+
end
|
8
13
|
end
|
9
14
|
|
10
15
|
Rake::Task[:merb_env].invoke if defined?(Merb)
|
@@ -106,7 +106,7 @@ describe "ThinkingSphinx::ActiveRecord::Delta" do
|
|
106
106
|
|
107
107
|
it "should call indexer for the delta index" do
|
108
108
|
Person.sphinx_indexes.first.delta_object.should_receive(:`).with(
|
109
|
-
"#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config
|
109
|
+
"#{ThinkingSphinx::Configuration.instance.bin_path}indexer --config \"#{ThinkingSphinx::Configuration.instance.config_file}\" --rotate person_delta"
|
110
110
|
)
|
111
111
|
|
112
112
|
@person.send(:index_delta)
|
@@ -87,10 +87,9 @@ describe ThinkingSphinx::ActiveRecord::Scopes do
|
|
87
87
|
search.by_foo('foo').search.options[:conditions].should == {:foo => 'foo', :name => 'foo'}
|
88
88
|
end
|
89
89
|
|
90
|
-
|
91
|
-
it "should apply the default scope options after other scope options to the underlying search object" do
|
90
|
+
it "should apply the default scope options before other scope options to the underlying search object" do
|
92
91
|
search = ThinkingSphinx::Search.new(:classes => [Alpha])
|
93
|
-
search.by_name('bar').search.options[:conditions].should == {:name => '
|
92
|
+
search.by_name('bar').search.options[:conditions].should == {:name => 'bar'}
|
94
93
|
end
|
95
94
|
end
|
96
95
|
|
@@ -22,6 +22,14 @@ describe ThinkingSphinx::AutoVersion do
|
|
22
22
|
ThinkingSphinx::AutoVersion.detect
|
23
23
|
end
|
24
24
|
|
25
|
+
it "should require 1.10-beta if that is the detected version" do
|
26
|
+
ThinkingSphinx::AutoVersion.should_receive(:require).
|
27
|
+
with('riddle/1.10')
|
28
|
+
|
29
|
+
@config.stub!(:version => '1.10-beta')
|
30
|
+
ThinkingSphinx::AutoVersion.detect
|
31
|
+
end
|
32
|
+
|
25
33
|
it "should output a warning if the detected version is something else" do
|
26
34
|
STDERR.should_receive(:puts)
|
27
35
|
|
@@ -53,8 +53,9 @@ describe ThinkingSphinx::Context do
|
|
53
53
|
|
54
54
|
it "should catch database errors with a warning" do
|
55
55
|
@class_name.should_receive(:constantize).and_raise(Mysql::Error)
|
56
|
-
STDERR.
|
57
|
-
|
56
|
+
STDERR.stub!(:puts => '')
|
57
|
+
STDERR.should_receive(:puts).with('Warning: Error loading a.rb:')
|
58
|
+
|
58
59
|
lambda {
|
59
60
|
@context.prepare
|
60
61
|
}.should_not raise_error
|
@@ -1,28 +1,26 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ThinkingSphinx::FacetSearch do
|
4
|
+
let(:search) { stub('search', :append_to => nil, :empty? => true) }
|
5
|
+
let(:config) { ThinkingSphinx::Configuration.instance }
|
6
|
+
let(:client) { stub('client', :run => []) }
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
config.stub!(:client => client)
|
10
|
+
end
|
11
|
+
|
4
12
|
describe 'populate' do
|
5
|
-
|
6
|
-
|
7
|
-
hash_including(:group_by => 'city_facet')
|
8
|
-
).and_return([])
|
9
|
-
ThinkingSphinx.should_receive(:search).with(
|
10
|
-
hash_including(:group_by => 'state_facet')
|
11
|
-
).and_return([])
|
12
|
-
ThinkingSphinx.should_receive(:search).with(
|
13
|
-
hash_including(:group_by => 'birthday')
|
14
|
-
).and_return([])
|
15
|
-
|
16
|
-
ThinkingSphinx::FacetSearch.new(:classes => [Person])
|
13
|
+
before :each do
|
14
|
+
config.configuration.searchd.max_matches = 10_000
|
17
15
|
end
|
18
|
-
|
16
|
+
|
19
17
|
it "should request all shared facets in a multi-model request by default" do
|
20
|
-
ThinkingSphinx.stub!(:search =>
|
18
|
+
ThinkingSphinx.stub!(:search => search)
|
21
19
|
ThinkingSphinx::FacetSearch.new.facet_names.should == ['class_crc']
|
22
20
|
end
|
23
21
|
|
24
22
|
it "should request all facets in a multi-model request if specified" do
|
25
|
-
ThinkingSphinx.stub!(:search =>
|
23
|
+
ThinkingSphinx.stub!(:search => search)
|
26
24
|
ThinkingSphinx::FacetSearch.new(
|
27
25
|
:all_facets => true
|
28
26
|
).facet_names.should == [
|
@@ -30,80 +28,22 @@ describe ThinkingSphinx::FacetSearch do
|
|
30
28
|
]
|
31
29
|
end
|
32
30
|
|
33
|
-
describe ':facets option' do
|
34
|
-
it "should limit facets to the requested set" do
|
35
|
-
ThinkingSphinx.should_receive(:search).once.and_return([])
|
36
|
-
|
37
|
-
ThinkingSphinx::FacetSearch.new(
|
38
|
-
:classes => [Person], :facets => :state
|
39
|
-
)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe "empty result set for attributes" do
|
44
|
-
before :each do
|
45
|
-
ThinkingSphinx.stub!(:search => [])
|
46
|
-
@facets = ThinkingSphinx::FacetSearch.new(
|
47
|
-
:classes => [Person], :facets => :state
|
48
|
-
)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should add key as attribute" do
|
52
|
-
@facets.should have_key(:state)
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should return an empty hash for the facet results" do
|
56
|
-
@facets[:state].should be_empty
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "non-empty result set" do
|
61
|
-
before :each do
|
62
|
-
@person = Person.find(:first)
|
63
|
-
@people = [@person]
|
64
|
-
@people.stub!(:each_with_groupby_and_count).
|
65
|
-
and_yield(@person, @person.city.to_crc32, 1)
|
66
|
-
ThinkingSphinx.stub!(:search => @people)
|
67
|
-
|
68
|
-
@facets = ThinkingSphinx::FacetSearch.new(
|
69
|
-
:classes => [Person], :facets => :city
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should return a hash" do
|
74
|
-
@facets.should be_a_kind_of(Hash)
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should add key as attribute" do
|
78
|
-
@facets.keys.should include(:city)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should return a hash" do
|
82
|
-
@facets[:city].should == {@person.city => 1}
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
before :each do
|
87
|
-
@config = ThinkingSphinx::Configuration.instance
|
88
|
-
@config.configuration.searchd.max_matches = 10_000
|
89
|
-
end
|
90
|
-
|
91
31
|
it "should use the system-set max_matches for limit on facet calls" do
|
92
32
|
ThinkingSphinx.should_receive(:search) do |options|
|
93
33
|
options[:max_matches].should == 10_000
|
94
34
|
options[:limit].should == 10_000
|
95
|
-
|
35
|
+
search
|
96
36
|
end
|
97
37
|
|
98
38
|
ThinkingSphinx::FacetSearch.new
|
99
39
|
end
|
100
40
|
|
101
41
|
it "should use the default max-matches if there is no explicit setting" do
|
102
|
-
|
42
|
+
config.configuration.searchd.max_matches = nil
|
103
43
|
ThinkingSphinx.should_receive(:search) do |options|
|
104
44
|
options[:max_matches].should == 1000
|
105
45
|
options[:limit].should == 1000
|
106
|
-
|
46
|
+
search
|
107
47
|
end
|
108
48
|
|
109
49
|
ThinkingSphinx::FacetSearch.new
|
@@ -113,7 +53,7 @@ describe ThinkingSphinx::FacetSearch do
|
|
113
53
|
ThinkingSphinx.should_receive(:search) do |options|
|
114
54
|
options[:max_matches].should == 10_000
|
115
55
|
options[:limit].should == 10_000
|
116
|
-
|
56
|
+
search
|
117
57
|
end
|
118
58
|
|
119
59
|
ThinkingSphinx::FacetSearch.new(
|
@@ -125,7 +65,7 @@ describe ThinkingSphinx::FacetSearch do
|
|
125
65
|
it "should not use an explicit :page" do
|
126
66
|
ThinkingSphinx.should_receive(:search) do |options|
|
127
67
|
options[:page].should == 1
|
128
|
-
|
68
|
+
search
|
129
69
|
end
|
130
70
|
|
131
71
|
ThinkingSphinx::FacetSearch.new(:page => 3)
|
@@ -149,15 +89,69 @@ describe ThinkingSphinx::FacetSearch do
|
|
149
89
|
}.should raise_error
|
150
90
|
end
|
151
91
|
end
|
92
|
+
|
93
|
+
describe ':facets option' do
|
94
|
+
it "should limit facets to the requested set" do
|
95
|
+
ThinkingSphinx.should_receive(:search).once.and_return(search)
|
96
|
+
|
97
|
+
ThinkingSphinx::FacetSearch.new(
|
98
|
+
:classes => [Person], :facets => :state
|
99
|
+
)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "empty result set for attributes" do
|
104
|
+
before :each do
|
105
|
+
ThinkingSphinx.stub!(:search => search)
|
106
|
+
@facets = ThinkingSphinx::FacetSearch.new(
|
107
|
+
:classes => [Person], :facets => :state
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should add key as attribute" do
|
112
|
+
@facets.should have_key(:state)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should return an empty hash for the facet results" do
|
116
|
+
@facets[:state].should be_empty
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "non-empty result set" do
|
121
|
+
before :each do
|
122
|
+
@person = Person.find(:first)
|
123
|
+
@people = [@person]
|
124
|
+
search.stub!(:empty? => false)
|
125
|
+
search.stub!(:each_with_match).
|
126
|
+
and_yield(@person, {:attributes => {'@groupby' => @person.city.to_crc32, '@count' => 1}})
|
127
|
+
ThinkingSphinx::Search.stub!(:bundle_searches => [search])
|
128
|
+
|
129
|
+
@facets = ThinkingSphinx::FacetSearch.new(
|
130
|
+
:classes => [Person], :facets => :city
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should return a hash" do
|
135
|
+
@facets.should be_a_kind_of(Hash)
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should add key as attribute" do
|
139
|
+
@facets.keys.should include(:city)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should return a hash" do
|
143
|
+
@facets[:city].should == {@person.city => 1}
|
144
|
+
end
|
145
|
+
end
|
152
146
|
end
|
153
147
|
|
154
148
|
describe "#for" do
|
155
149
|
before do
|
156
150
|
@person = Person.find(:first)
|
157
151
|
@people = [@person]
|
158
|
-
|
159
|
-
and_yield(@person, @person.city.to_crc32, 1)
|
160
|
-
ThinkingSphinx.stub!(:
|
152
|
+
search.stub!(:each_with_match).
|
153
|
+
and_yield(@person, {:attributes => {'@groupby' => @person.city.to_crc32, '@count' => 1}})
|
154
|
+
ThinkingSphinx::Search.stub!(:bundle_searches => [search])
|
161
155
|
|
162
156
|
@facets = ThinkingSphinx::FacetSearch.new(
|
163
157
|
:classes => [Person], :facets => :city
|
@@ -291,13 +291,13 @@ describe ThinkingSphinx::Facet do
|
|
291
291
|
person = Person.find(:first)
|
292
292
|
friendship = Friendship.new(:person => person)
|
293
293
|
|
294
|
-
@facet.value(friendship, 1).should == person.first_name
|
294
|
+
@facet.value(friendship, {'first_name_facet' => 1}).should == person.first_name
|
295
295
|
end
|
296
296
|
|
297
297
|
it "should return nil if the association is nil" do
|
298
298
|
friendship = Friendship.new(:person => nil)
|
299
299
|
|
300
|
-
@facet.value(friendship, 1).should be_nil
|
300
|
+
@facet.value(friendship, {'first_name_facet' => 1}).should be_nil
|
301
301
|
end
|
302
302
|
|
303
303
|
it "should return multi-level association values" do
|
@@ -308,7 +308,7 @@ describe ThinkingSphinx::Facet do
|
|
308
308
|
field = ThinkingSphinx::Field.new(
|
309
309
|
@source, ThinkingSphinx::Index::FauxColumn.new(:person, :tags, :name)
|
310
310
|
)
|
311
|
-
ThinkingSphinx::Facet.new(field).value(friendship, 'buried'.to_crc32).
|
311
|
+
ThinkingSphinx::Facet.new(field).value(friendship, {'name_facet' => 'buried'.to_crc32}).
|
312
312
|
should == 'buried'
|
313
313
|
end
|
314
314
|
end
|
@@ -326,7 +326,7 @@ describe ThinkingSphinx::Facet do
|
|
326
326
|
it "should translate using the given model" do
|
327
327
|
alpha = Alpha.new(:cost => 10.5)
|
328
328
|
|
329
|
-
@facet.value(alpha, 1093140480).should == 10.5
|
329
|
+
@facet.value(alpha, {'cost' => 1093140480}).should == 10.5
|
330
330
|
end
|
331
331
|
end
|
332
332
|
end
|
@@ -135,6 +135,10 @@ describe ThinkingSphinx::SearchMethods do
|
|
135
135
|
end
|
136
136
|
|
137
137
|
describe '.facets' do
|
138
|
+
before :each do
|
139
|
+
ThinkingSphinx::Search.stub!(:bundle_searches => [])
|
140
|
+
end
|
141
|
+
|
138
142
|
it "should return a FacetSearch instance" do
|
139
143
|
Alpha.facets.should be_a(ThinkingSphinx::FacetSearch)
|
140
144
|
end
|
@@ -785,9 +785,10 @@ describe ThinkingSphinx::Search do
|
|
785
785
|
end
|
786
786
|
|
787
787
|
it "should set up the excerpter with the instances and search" do
|
788
|
-
|
789
|
-
|
790
|
-
|
788
|
+
[@alpha_a, @beta_b, @alpha_b, @beta_a].each do |object|
|
789
|
+
ThinkingSphinx::Excerpter.should_receive(:new).with(@search, object)
|
790
|
+
end
|
791
|
+
|
791
792
|
@search.first
|
792
793
|
end
|
793
794
|
end
|
@@ -822,11 +823,6 @@ describe ThinkingSphinx::Search do
|
|
822
823
|
search.first.should respond_to(:matching_fields)
|
823
824
|
end
|
824
825
|
|
825
|
-
it "should not add matching_fields method if using a different ranking mode" do
|
826
|
-
search = ThinkingSphinx::Search.new :rank_mode => :bm25
|
827
|
-
search.first.should_not respond_to(:matching_fields)
|
828
|
-
end
|
829
|
-
|
830
826
|
it "should not add matching_fields method if object already have one" do
|
831
827
|
search = ThinkingSphinx::Search.new :rank_mode => :fieldmask
|
832
828
|
search.last.matching_fields.should_not be_an(Array)
|
@@ -1112,6 +1108,15 @@ describe ThinkingSphinx::Search do
|
|
1112
1108
|
@search.excerpt_for('string')
|
1113
1109
|
end
|
1114
1110
|
|
1111
|
+
it "should respect the provided index option" do
|
1112
|
+
@search = ThinkingSphinx::Search.new(:classes => [Alpha], :index => 'foo')
|
1113
|
+
@client.should_receive(:excerpts) do |options|
|
1114
|
+
options[:index].should == 'foo'
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
@search.excerpt_for('string')
|
1118
|
+
end
|
1119
|
+
|
1115
1120
|
it "should optionally take a second argument to allow for multi-model searches" do
|
1116
1121
|
@client.should_receive(:excerpts) do |options|
|
1117
1122
|
options[:index].should == 'beta_core'
|
@@ -1197,6 +1202,19 @@ describe ThinkingSphinx::Search do
|
|
1197
1202
|
@search.freeze.should be_a(ThinkingSphinx::Search)
|
1198
1203
|
end
|
1199
1204
|
end
|
1205
|
+
|
1206
|
+
describe '#client' do
|
1207
|
+
let(:client) { Riddle::Client.new }
|
1208
|
+
it "should respect the client in options" do
|
1209
|
+
search = ThinkingSphinx::Search.new :client => client
|
1210
|
+
search.client.should == client
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
it "should get a new client from the configuration singleton by default" do
|
1214
|
+
ThinkingSphinx::Configuration.instance.stub!(:client => client)
|
1215
|
+
ThinkingSphinx::Search.new.client.should == client
|
1216
|
+
end
|
1217
|
+
end
|
1200
1218
|
end
|
1201
1219
|
|
1202
1220
|
describe ThinkingSphinx::Search, "playing nice with Search model" do
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "#{File.dirname(__FILE__)}/../../lib/thinking_sphinx/test"
|
3
|
+
|
4
|
+
describe ThinkingSphinx::Test do
|
5
|
+
describe ".run" do
|
6
|
+
before :each do
|
7
|
+
ThinkingSphinx::Test.stub!(:start)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should call stop when an exception is raised by passed block" do
|
11
|
+
ThinkingSphinx::Test.should_receive(:stop)
|
12
|
+
|
13
|
+
begin
|
14
|
+
ThinkingSphinx::Test.run { raise FakeError }
|
15
|
+
rescue => FakeError
|
16
|
+
# we raised it manually ourselves!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/tasks/distribution.rb
CHANGED
@@ -23,11 +23,13 @@ Jeweler::Tasks.new do |gem|
|
|
23
23
|
"VERSION"
|
24
24
|
]
|
25
25
|
gem.test_files = FileList[
|
26
|
-
"features
|
26
|
+
"features/**/*.rb",
|
27
|
+
"features/**/*.feature",
|
28
|
+
"features/**/*.example.yml",
|
27
29
|
"spec/**/*_spec.rb"
|
28
30
|
]
|
29
31
|
|
30
|
-
gem.add_dependency 'activerecord', '>= 1.15.6'
|
32
|
+
gem.add_dependency 'activerecord', '>= 1.15.6', '< 3.0.0'
|
31
33
|
gem.add_dependency 'riddle', '>= 1.0.10'
|
32
34
|
gem.add_dependency 'after_commit', '>= 1.0.6'
|
33
35
|
|
metadata
CHANGED
@@ -3,10 +3,9 @@ name: thorsson_thinking-sphinx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
-
-
|
7
|
-
-
|
8
|
-
|
9
|
-
version: 1.3.18
|
6
|
+
- 2
|
7
|
+
- 0
|
8
|
+
version: "2.0"
|
10
9
|
platform: ruby
|
11
10
|
authors:
|
12
11
|
- Pat Allan
|
@@ -14,7 +13,7 @@ autorequire:
|
|
14
13
|
bindir: bin
|
15
14
|
cert_chain: []
|
16
15
|
|
17
|
-
date: 2010-
|
16
|
+
date: 2010-09-03 00:00:00 +02:00
|
18
17
|
default_executable:
|
19
18
|
dependencies:
|
20
19
|
- !ruby/object:Gem::Dependency
|
@@ -30,6 +29,13 @@ dependencies:
|
|
30
29
|
- 15
|
31
30
|
- 6
|
32
31
|
version: 1.15.6
|
32
|
+
- - <
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
segments:
|
35
|
+
- 3
|
36
|
+
- 0
|
37
|
+
- 0
|
38
|
+
version: 3.0.0
|
33
39
|
type: :runtime
|
34
40
|
version_requirements: *id001
|
35
41
|
- !ruby/object:Gem::Dependency
|
@@ -175,6 +181,7 @@ files:
|
|
175
181
|
- lib/thinking_sphinx/association.rb
|
176
182
|
- lib/thinking_sphinx/attribute.rb
|
177
183
|
- lib/thinking_sphinx/auto_version.rb
|
184
|
+
- lib/thinking_sphinx/bundled_search.rb
|
178
185
|
- lib/thinking_sphinx/class_facet.rb
|
179
186
|
- lib/thinking_sphinx/configuration.rb
|
180
187
|
- lib/thinking_sphinx/context.rb
|
@@ -204,24 +211,6 @@ files:
|
|
204
211
|
- tasks/distribution.rb
|
205
212
|
- tasks/rails.rake
|
206
213
|
- tasks/testing.rb
|
207
|
-
- features/abstract_inheritance.feature
|
208
|
-
- features/alternate_primary_key.feature
|
209
|
-
- features/attribute_transformation.feature
|
210
|
-
- features/attribute_updates.feature
|
211
|
-
- features/deleting_instances.feature
|
212
|
-
- features/direct_attributes.feature
|
213
|
-
- features/excerpts.feature
|
214
|
-
- features/extensible_delta_indexing.feature
|
215
|
-
- features/facets.feature
|
216
|
-
- features/facets_across_model.feature
|
217
|
-
- features/handling_edits.feature
|
218
|
-
- features/retry_stale_indexes.feature
|
219
|
-
- features/searching_across_models.feature
|
220
|
-
- features/searching_by_index.feature
|
221
|
-
- features/searching_by_model.feature
|
222
|
-
- features/searching_with_find_arguments.feature
|
223
|
-
- features/sphinx_detection.feature
|
224
|
-
- features/sphinx_scopes.feature
|
225
214
|
- features/step_definitions/alpha_steps.rb
|
226
215
|
- features/step_definitions/beta_steps.rb
|
227
216
|
- features/step_definitions/common_steps.rb
|
@@ -232,11 +221,9 @@ files:
|
|
232
221
|
- features/step_definitions/scope_steps.rb
|
233
222
|
- features/step_definitions/search_steps.rb
|
234
223
|
- features/step_definitions/sphinx_steps.rb
|
235
|
-
- features/sti_searching.feature
|
236
224
|
- features/support/env.rb
|
237
225
|
- features/support/lib/generic_delta_handler.rb
|
238
226
|
- features/thinking_sphinx/database.example.yml
|
239
|
-
- features/thinking_sphinx/database.yml
|
240
227
|
- features/thinking_sphinx/db/fixtures/alphas.rb
|
241
228
|
- features/thinking_sphinx/db/fixtures/authors.rb
|
242
229
|
- features/thinking_sphinx/db/fixtures/betas.rb
|
@@ -293,6 +280,25 @@ files:
|
|
293
280
|
- features/thinking_sphinx/models/robot.rb
|
294
281
|
- features/thinking_sphinx/models/tag.rb
|
295
282
|
- features/thinking_sphinx/models/tagging.rb
|
283
|
+
- features/abstract_inheritance.feature
|
284
|
+
- features/alternate_primary_key.feature
|
285
|
+
- features/attribute_transformation.feature
|
286
|
+
- features/attribute_updates.feature
|
287
|
+
- features/deleting_instances.feature
|
288
|
+
- features/direct_attributes.feature
|
289
|
+
- features/excerpts.feature
|
290
|
+
- features/extensible_delta_indexing.feature
|
291
|
+
- features/facets.feature
|
292
|
+
- features/facets_across_model.feature
|
293
|
+
- features/handling_edits.feature
|
294
|
+
- features/retry_stale_indexes.feature
|
295
|
+
- features/searching_across_models.feature
|
296
|
+
- features/searching_by_index.feature
|
297
|
+
- features/searching_by_model.feature
|
298
|
+
- features/searching_with_find_arguments.feature
|
299
|
+
- features/sphinx_detection.feature
|
300
|
+
- features/sphinx_scopes.feature
|
301
|
+
- features/sti_searching.feature
|
296
302
|
- spec/thinking_sphinx/active_record/delta_spec.rb
|
297
303
|
- spec/thinking_sphinx/active_record/has_many_association_spec.rb
|
298
304
|
- spec/thinking_sphinx/active_record/scopes_spec.rb
|
@@ -315,6 +321,7 @@ files:
|
|
315
321
|
- spec/thinking_sphinx/search_methods_spec.rb
|
316
322
|
- spec/thinking_sphinx/search_spec.rb
|
317
323
|
- spec/thinking_sphinx/source_spec.rb
|
324
|
+
- spec/thinking_sphinx/test_spec.rb
|
318
325
|
- spec/thinking_sphinx_spec.rb
|
319
326
|
has_rdoc: true
|
320
327
|
homepage: http://ts.freelancing-gods.com
|
@@ -352,24 +359,6 @@ signing_key:
|
|
352
359
|
specification_version: 3
|
353
360
|
summary: ActiveRecord/Rails Sphinx library
|
354
361
|
test_files:
|
355
|
-
- features/abstract_inheritance.feature
|
356
|
-
- features/alternate_primary_key.feature
|
357
|
-
- features/attribute_transformation.feature
|
358
|
-
- features/attribute_updates.feature
|
359
|
-
- features/deleting_instances.feature
|
360
|
-
- features/direct_attributes.feature
|
361
|
-
- features/excerpts.feature
|
362
|
-
- features/extensible_delta_indexing.feature
|
363
|
-
- features/facets.feature
|
364
|
-
- features/facets_across_model.feature
|
365
|
-
- features/handling_edits.feature
|
366
|
-
- features/retry_stale_indexes.feature
|
367
|
-
- features/searching_across_models.feature
|
368
|
-
- features/searching_by_index.feature
|
369
|
-
- features/searching_by_model.feature
|
370
|
-
- features/searching_with_find_arguments.feature
|
371
|
-
- features/sphinx_detection.feature
|
372
|
-
- features/sphinx_scopes.feature
|
373
362
|
- features/step_definitions/alpha_steps.rb
|
374
363
|
- features/step_definitions/beta_steps.rb
|
375
364
|
- features/step_definitions/common_steps.rb
|
@@ -380,11 +369,9 @@ test_files:
|
|
380
369
|
- features/step_definitions/scope_steps.rb
|
381
370
|
- features/step_definitions/search_steps.rb
|
382
371
|
- features/step_definitions/sphinx_steps.rb
|
383
|
-
- features/sti_searching.feature
|
384
372
|
- features/support/env.rb
|
385
373
|
- features/support/lib/generic_delta_handler.rb
|
386
374
|
- features/thinking_sphinx/database.example.yml
|
387
|
-
- features/thinking_sphinx/database.yml
|
388
375
|
- features/thinking_sphinx/db/fixtures/alphas.rb
|
389
376
|
- features/thinking_sphinx/db/fixtures/authors.rb
|
390
377
|
- features/thinking_sphinx/db/fixtures/betas.rb
|
@@ -441,6 +428,26 @@ test_files:
|
|
441
428
|
- features/thinking_sphinx/models/robot.rb
|
442
429
|
- features/thinking_sphinx/models/tag.rb
|
443
430
|
- features/thinking_sphinx/models/tagging.rb
|
431
|
+
- features/abstract_inheritance.feature
|
432
|
+
- features/alternate_primary_key.feature
|
433
|
+
- features/attribute_transformation.feature
|
434
|
+
- features/attribute_updates.feature
|
435
|
+
- features/deleting_instances.feature
|
436
|
+
- features/direct_attributes.feature
|
437
|
+
- features/excerpts.feature
|
438
|
+
- features/extensible_delta_indexing.feature
|
439
|
+
- features/facets.feature
|
440
|
+
- features/facets_across_model.feature
|
441
|
+
- features/handling_edits.feature
|
442
|
+
- features/retry_stale_indexes.feature
|
443
|
+
- features/searching_across_models.feature
|
444
|
+
- features/searching_by_index.feature
|
445
|
+
- features/searching_by_model.feature
|
446
|
+
- features/searching_with_find_arguments.feature
|
447
|
+
- features/sphinx_detection.feature
|
448
|
+
- features/sphinx_scopes.feature
|
449
|
+
- features/sti_searching.feature
|
450
|
+
- features/thinking_sphinx/database.example.yml
|
444
451
|
- spec/thinking_sphinx/active_record/delta_spec.rb
|
445
452
|
- spec/thinking_sphinx/active_record/has_many_association_spec.rb
|
446
453
|
- spec/thinking_sphinx/active_record/scopes_spec.rb
|
@@ -463,4 +470,5 @@ test_files:
|
|
463
470
|
- spec/thinking_sphinx/search_methods_spec.rb
|
464
471
|
- spec/thinking_sphinx/search_spec.rb
|
465
472
|
- spec/thinking_sphinx/source_spec.rb
|
473
|
+
- spec/thinking_sphinx/test_spec.rb
|
466
474
|
- spec/thinking_sphinx_spec.rb
|