thinking-sphinx 1.4.1 → 1.4.2
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.textile +3 -0
- data/VERSION +1 -1
- data/features/facets.feature +18 -20
- data/features/thinking_sphinx/db/fixtures/cats.rb +1 -1
- data/features/thinking_sphinx/db/fixtures/dogs.rb +1 -1
- data/features/thinking_sphinx/db/fixtures/foxes.rb +1 -1
- data/features/thinking_sphinx/models/developer.rb +5 -1
- data/lib/thinking_sphinx/active_record.rb +2 -0
- data/lib/thinking_sphinx/active_record/attribute_updates.rb +2 -0
- data/lib/thinking_sphinx/adapters/abstract_adapter.rb +9 -0
- data/lib/thinking_sphinx/attribute.rb +1 -1
- data/lib/thinking_sphinx/configuration.rb +23 -0
- data/lib/thinking_sphinx/deltas/default_delta.rb +4 -4
- data/lib/thinking_sphinx/deploy/capistrano.rb +3 -2
- data/lib/thinking_sphinx/facet.rb +6 -4
- data/lib/thinking_sphinx/facet_search.rb +2 -0
- data/lib/thinking_sphinx/field.rb +2 -0
- data/lib/thinking_sphinx/property.rb +24 -7
- data/lib/thinking_sphinx/search.rb +4 -2
- data/lib/thinking_sphinx/source.rb +5 -1
- data/lib/thinking_sphinx/source/sql.rb +20 -4
- data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +11 -0
- data/spec/thinking_sphinx/attribute_spec.rb +9 -0
- data/spec/thinking_sphinx/configuration_spec.rb +17 -0
- data/spec/thinking_sphinx/facet_spec.rb +14 -0
- data/spec/thinking_sphinx/field_spec.rb +11 -0
- data/spec/thinking_sphinx/source_spec.rb +10 -0
- metadata +7 -7
data/README.textile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.
|
1
|
+
1.4.2
|
data/features/facets.feature
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
Feature: Search and browse models by their defined facets
|
2
2
|
|
3
|
-
|
3
|
+
Background:
|
4
4
|
Given Sphinx is running
|
5
|
-
|
5
|
+
|
6
|
+
Scenario: Requesting facets
|
7
|
+
Given I am searching on developers
|
6
8
|
When I am requesting facet results
|
7
9
|
Then I should have valid facet results
|
8
10
|
And I should have 6 facets
|
@@ -14,8 +16,7 @@ Feature: Search and browse models by their defined facets
|
|
14
16
|
And I should have the facet Tags
|
15
17
|
|
16
18
|
Scenario: Requesting specific facets
|
17
|
-
Given
|
18
|
-
And I am searching on developers
|
19
|
+
Given I am searching on developers
|
19
20
|
When I am requesting facet results
|
20
21
|
And I am requesting just the facet State
|
21
22
|
Then I should have valid facet results
|
@@ -28,29 +29,25 @@ Feature: Search and browse models by their defined facets
|
|
28
29
|
And I should have the facet Age
|
29
30
|
|
30
31
|
Scenario: Requesting float facets
|
31
|
-
Given
|
32
|
-
And I am searching on alphas
|
32
|
+
Given I am searching on alphas
|
33
33
|
When I am requesting facet results
|
34
34
|
Then I should have 1 facet
|
35
35
|
And the Cost facet should have a 5.55 key
|
36
36
|
|
37
37
|
Scenario: Requesting facet results
|
38
|
-
Given
|
39
|
-
And I am searching on developers
|
38
|
+
Given I am searching on developers
|
40
39
|
When I am requesting facet results
|
41
40
|
And I drill down where Country is Australia
|
42
41
|
Then I should get 11 results
|
43
42
|
|
44
43
|
Scenario: Requesting facet results by multiple facets
|
45
|
-
Given
|
46
|
-
And I am searching on developers
|
44
|
+
Given I am searching on developers
|
47
45
|
When I am requesting facet results
|
48
46
|
And I drill down where Country is Australia and Age is 30
|
49
47
|
Then I should get 4 results
|
50
48
|
|
51
49
|
Scenario: Requesting facets with classes included
|
52
|
-
Given
|
53
|
-
And I am searching on developers
|
50
|
+
Given I am searching on developers
|
54
51
|
When I am requesting facet results
|
55
52
|
And I want classes included
|
56
53
|
Then I should have valid facet results
|
@@ -58,8 +55,7 @@ Feature: Search and browse models by their defined facets
|
|
58
55
|
And I should have the facet Class
|
59
56
|
|
60
57
|
Scenario: Requesting MVA facets
|
61
|
-
Given
|
62
|
-
And I am searching on developers
|
58
|
+
Given I am searching on developers
|
63
59
|
When I am requesting facet results
|
64
60
|
And I drill down where tag_ids includes the id of tag Australia
|
65
61
|
Then I should get 11 results
|
@@ -68,23 +64,25 @@ Feature: Search and browse models by their defined facets
|
|
68
64
|
Then I should get 5 results
|
69
65
|
|
70
66
|
Scenario: Requesting MVA string facets
|
71
|
-
Given
|
72
|
-
And I am searching on developers
|
67
|
+
Given I am searching on developers
|
73
68
|
When I am requesting facet results
|
74
69
|
Then the Tags facet should have an "Australia" key
|
75
70
|
Then the Tags facet should have an "Melbourne" key
|
76
71
|
Then the Tags facet should have an "Victoria" key
|
77
72
|
|
78
73
|
Scenario: Requesting MVA facets from source queries
|
79
|
-
Given
|
80
|
-
And I am searching on posts
|
74
|
+
Given I am searching on posts
|
81
75
|
When I am requesting facet results
|
82
76
|
Then the Comment Ids facet should have 9 keys
|
83
77
|
|
84
78
|
Scenario: Requesting facets from a subclass
|
85
|
-
Given
|
86
|
-
And I am searching on animals
|
79
|
+
Given I am searching on animals
|
87
80
|
When I am requesting facet results
|
88
81
|
And I want classes included
|
89
82
|
Then I should have the facet Class
|
90
83
|
|
84
|
+
Scenario: Requesting facets with explicit value sources
|
85
|
+
Given I am searching on developers
|
86
|
+
When I am requesting facet results
|
87
|
+
Then the City facet should have a "Melbourne" key
|
88
|
+
|
@@ -9,8 +9,12 @@ class Developer < ActiveRecord::Base
|
|
9
9
|
indexes country, :facet => true
|
10
10
|
indexes state, :facet => true
|
11
11
|
indexes tags.text, :as => :tags, :facet => true
|
12
|
+
|
12
13
|
has age, :facet => true
|
13
14
|
has tags(:id), :as => :tag_ids, :facet => true
|
14
|
-
|
15
|
+
|
16
|
+
facet "LOWER(city)", :as => :city, :type => :string, :value => :city
|
17
|
+
|
18
|
+
group_by 'city'
|
15
19
|
end
|
16
20
|
end
|
@@ -258,6 +258,8 @@ module ThinkingSphinx
|
|
258
258
|
ThinkingSphinx::Configuration.instance.client.update(
|
259
259
|
index, ['sphinx_deleted'], {document_id => [1]}
|
260
260
|
)
|
261
|
+
rescue Riddle::ConnectionError, ThinkingSphinx::SphinxError
|
262
|
+
# Not the end of the world if Sphinx isn't running.
|
261
263
|
end
|
262
264
|
|
263
265
|
def sphinx_offset
|
@@ -44,6 +44,8 @@ module ThinkingSphinx
|
|
44
44
|
config.client.update index_name, attribute_names, {
|
45
45
|
sphinx_document_id => attribute_values
|
46
46
|
} if self.class.search_for_id(sphinx_document_id, index_name)
|
47
|
+
rescue Riddle::ConnectionError, ThinkingSphinx::SphinxError
|
48
|
+
# Not the end of the world if Sphinx isn't running.
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
@@ -16,6 +16,8 @@ module ThinkingSphinx
|
|
16
16
|
ThinkingSphinx::MysqlAdapter.new model
|
17
17
|
when :postgresql
|
18
18
|
ThinkingSphinx::PostgreSQLAdapter.new model
|
19
|
+
when Class
|
20
|
+
adapter.new model
|
19
21
|
else
|
20
22
|
raise "Invalid Database Adapter: Sphinx only supports MySQL and PostgreSQL, not #{adapter}"
|
21
23
|
end
|
@@ -69,6 +71,13 @@ module ThinkingSphinx
|
|
69
71
|
"LOWER(#{clause})"
|
70
72
|
end
|
71
73
|
|
74
|
+
def case(expression, pairs, default)
|
75
|
+
"CASE #{expression} " +
|
76
|
+
pairs.keys.inject('') { |string, key|
|
77
|
+
string + "WHEN '#{key}' THEN #{pairs[key]} "
|
78
|
+
} + "ELSE #{default} END"
|
79
|
+
end
|
80
|
+
|
72
81
|
protected
|
73
82
|
|
74
83
|
def connection
|
@@ -89,7 +89,7 @@ module ThinkingSphinx
|
|
89
89
|
# datetimes to timestamps, as needed.
|
90
90
|
#
|
91
91
|
def to_select_sql
|
92
|
-
return nil unless include_as_association?
|
92
|
+
return nil unless include_as_association? && available?
|
93
93
|
|
94
94
|
separator = all_ints? || all_datetimes? || @crc ? ',' : ' '
|
95
95
|
|
@@ -147,6 +147,8 @@ module ThinkingSphinx
|
|
147
147
|
model = model.constantize
|
148
148
|
model.define_indexes
|
149
149
|
@configuration.indexes.concat model.to_riddle
|
150
|
+
|
151
|
+
enforce_common_attribute_types
|
150
152
|
end
|
151
153
|
end
|
152
154
|
|
@@ -296,5 +298,26 @@ module ThinkingSphinx
|
|
296
298
|
send("#{key}=", value) if self.respond_to?("#{key}")
|
297
299
|
end
|
298
300
|
end
|
301
|
+
|
302
|
+
def enforce_common_attribute_types
|
303
|
+
sql_indexes = configuration.indexes.reject { |index|
|
304
|
+
index.is_a? Riddle::Configuration::DistributedIndex
|
305
|
+
}
|
306
|
+
|
307
|
+
return unless sql_indexes.any? { |index|
|
308
|
+
index.sources.any? { |source|
|
309
|
+
source.sql_attr_bigint.include? :sphinx_internal_id
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
sql_indexes.each { |index|
|
314
|
+
index.sources.each { |source|
|
315
|
+
next if source.sql_attr_bigint.include? :sphinx_internal_id
|
316
|
+
|
317
|
+
source.sql_attr_bigint << :sphinx_internal_id
|
318
|
+
source.sql_attr_uint.delete :sphinx_internal_id
|
319
|
+
}
|
320
|
+
}
|
321
|
+
end
|
299
322
|
end
|
300
323
|
end
|
@@ -20,13 +20,13 @@ module ThinkingSphinx
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def toggle(instance)
|
23
|
-
instance.
|
23
|
+
instance.send "#{@column}=", true
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def toggled(instance)
|
27
|
-
instance.
|
27
|
+
instance.send "#{@column}"
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def reset_query(model)
|
31
31
|
"UPDATE #{model.quoted_table_name} SET " +
|
32
32
|
"#{model.connection.quote_column_name(@column.to_s)} = #{adapter.boolean(false)} " +
|
@@ -84,9 +84,10 @@ DESC
|
|
84
84
|
start
|
85
85
|
end
|
86
86
|
|
87
|
-
desc "Add the shared folder for sphinx files
|
87
|
+
desc "Add the shared folder for sphinx files"
|
88
88
|
task :shared_sphinx_folder, :roles => :web do
|
89
|
-
|
89
|
+
rails_env = fetch(:rails_env, "production")
|
90
|
+
run "mkdir -p #{shared_path}/sphinx/#{rails_env}"
|
90
91
|
end
|
91
92
|
|
92
93
|
def rake(*tasks)
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module ThinkingSphinx
|
2
2
|
class Facet
|
3
|
-
attr_reader :property
|
3
|
+
attr_reader :property, :value_source
|
4
4
|
|
5
|
-
def initialize(property)
|
6
|
-
@property
|
5
|
+
def initialize(property, value_source = nil)
|
6
|
+
@property = property
|
7
|
+
@value_source = value_source
|
7
8
|
|
8
9
|
if property.columns.length != 1
|
9
10
|
raise "Can't translate Facets on multiple-column field or attribute"
|
@@ -104,7 +105,8 @@ module ThinkingSphinx
|
|
104
105
|
item.to_crc32 == attribute_value
|
105
106
|
}
|
106
107
|
else
|
107
|
-
|
108
|
+
method = value_source || column.__name
|
109
|
+
objects.first.send(method)
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
@@ -69,6 +69,8 @@ module ThinkingSphinx
|
|
69
69
|
# multiple data values (has_many or has_and_belongs_to_many associations).
|
70
70
|
#
|
71
71
|
def to_select_sql
|
72
|
+
return nil unless available?
|
73
|
+
|
72
74
|
clause = columns_with_prefixes.join(', ')
|
73
75
|
|
74
76
|
clause = adapter.concatenate(clause) if concat_ws?
|
@@ -10,10 +10,11 @@ module ThinkingSphinx
|
|
10
10
|
|
11
11
|
raise "Cannot define a field or attribute in #{source.model.name} with no columns. Maybe you are trying to index a field with a reserved name (id, name). You can fix this error by using a symbol rather than a bare name (:id instead of id)." if @columns.empty? || @columns.any? { |column| !column.respond_to?(:__stack) }
|
12
12
|
|
13
|
-
@alias
|
14
|
-
@faceted
|
15
|
-
@admin
|
16
|
-
@sortable
|
13
|
+
@alias = options[:as]
|
14
|
+
@faceted = options[:facet]
|
15
|
+
@admin = options[:admin]
|
16
|
+
@sortable = options[:sortable] || false
|
17
|
+
@value_source = options[:value]
|
17
18
|
|
18
19
|
@alias = @alias.to_sym unless @alias.blank?
|
19
20
|
|
@@ -40,7 +41,7 @@ module ThinkingSphinx
|
|
40
41
|
def to_facet
|
41
42
|
return nil unless @faceted
|
42
43
|
|
43
|
-
ThinkingSphinx::Facet.new(self)
|
44
|
+
ThinkingSphinx::Facet.new(self, @value_source)
|
44
45
|
end
|
45
46
|
|
46
47
|
# Get the part of the GROUP BY clause related to this attribute - if one is
|
@@ -77,6 +78,10 @@ module ThinkingSphinx
|
|
77
78
|
!admin
|
78
79
|
end
|
79
80
|
|
81
|
+
def available?
|
82
|
+
columns.any? { |column| column_available?(column) }
|
83
|
+
end
|
84
|
+
|
80
85
|
private
|
81
86
|
|
82
87
|
# Could there be more than one value related to the parent record? If so,
|
@@ -128,9 +133,11 @@ module ThinkingSphinx
|
|
128
133
|
# figure out how to correctly reference a column in SQL.
|
129
134
|
#
|
130
135
|
def column_with_prefix(column)
|
136
|
+
return nil unless column_available?(column)
|
137
|
+
|
131
138
|
if column.is_string?
|
132
139
|
column.__name
|
133
|
-
elsif
|
140
|
+
elsif column.__stack.empty?
|
134
141
|
"#{@model.quoted_table_name}.#{quote_column(column.__name)}"
|
135
142
|
else
|
136
143
|
associations[column].collect { |assoc|
|
@@ -144,7 +151,17 @@ module ThinkingSphinx
|
|
144
151
|
def columns_with_prefixes
|
145
152
|
@columns.collect { |column|
|
146
153
|
column_with_prefix column
|
147
|
-
}.flatten
|
154
|
+
}.flatten.compact
|
155
|
+
end
|
156
|
+
|
157
|
+
def column_available?(column)
|
158
|
+
if column.is_string?
|
159
|
+
true
|
160
|
+
elsif column.__stack.empty?
|
161
|
+
@model.column_names.include?(column.__name.to_s)
|
162
|
+
else
|
163
|
+
associations[column].any? { |assoc| assoc.has_column?(column.__name) }
|
164
|
+
end
|
148
165
|
end
|
149
166
|
|
150
167
|
# Gets a stack of associations for a specific path.
|
@@ -468,8 +468,10 @@ module ThinkingSphinx
|
|
468
468
|
end
|
469
469
|
|
470
470
|
def prepare(client)
|
471
|
-
index_options =
|
472
|
-
|
471
|
+
index_options = {}
|
472
|
+
if one_class && one_class.sphinx_indexes && one_class.sphinx_indexes.first
|
473
|
+
index_options = one_class.sphinx_indexes.first.local_options
|
474
|
+
end
|
473
475
|
|
474
476
|
[
|
475
477
|
:max_matches, :group_by, :group_function, :group_clause,
|
@@ -82,6 +82,10 @@ module ThinkingSphinx
|
|
82
82
|
@adapter ||= @model.sphinx_database_adapter
|
83
83
|
end
|
84
84
|
|
85
|
+
def available_attributes
|
86
|
+
attributes.select { |attrib| attrib.available? }
|
87
|
+
end
|
88
|
+
|
85
89
|
def set_source_database_settings(source)
|
86
90
|
config = @database_configuration
|
87
91
|
|
@@ -94,7 +98,7 @@ module ThinkingSphinx
|
|
94
98
|
end
|
95
99
|
|
96
100
|
def set_source_attributes(source, offset, delta = false)
|
97
|
-
|
101
|
+
available_attributes.each do |attrib|
|
98
102
|
source.send(attrib.type_to_config) << attrib.config_value(offset, delta)
|
99
103
|
end
|
100
104
|
end
|
@@ -117,14 +117,30 @@ GROUP BY #{ sql_group_clause }
|
|
117
117
|
if @model.table_exists? &&
|
118
118
|
@model.column_names.include?(@model.inheritance_column)
|
119
119
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
types = types_to_crcs
|
121
|
+
return @model.to_crc32.to_s if types.empty?
|
122
|
+
|
123
|
+
adapter.case(adapter.convert_nulls(
|
124
|
+
adapter.quote_with_table(@model.inheritance_column)),
|
125
|
+
types_to_crcs, @model.to_crc32)
|
124
126
|
else
|
125
127
|
@model.to_crc32.to_s
|
126
128
|
end
|
127
129
|
end
|
130
|
+
|
131
|
+
def type_values
|
132
|
+
@model.connection.select_values <<-SQL
|
133
|
+
SELECT DISTINCT #{@model.inheritance_column}
|
134
|
+
FROM #{@model.table_name}
|
135
|
+
SQL
|
136
|
+
end
|
137
|
+
|
138
|
+
def types_to_crcs
|
139
|
+
type_values.compact.inject({}) { |hash, type|
|
140
|
+
hash[type] = type.to_crc32
|
141
|
+
hash
|
142
|
+
}
|
143
|
+
end
|
128
144
|
end
|
129
145
|
end
|
130
146
|
end
|
@@ -1,5 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
class CustomAdapter < ThinkingSphinx::AbstractAdapter
|
4
|
+
#
|
5
|
+
end
|
6
|
+
|
3
7
|
describe ThinkingSphinx::AbstractAdapter do
|
4
8
|
describe '.detect' do
|
5
9
|
let(:model) { stub('model') }
|
@@ -18,6 +22,13 @@ describe ThinkingSphinx::AbstractAdapter do
|
|
18
22
|
adapter.should be_a(ThinkingSphinx::PostgreSQLAdapter)
|
19
23
|
end
|
20
24
|
|
25
|
+
it "instantiates the provided class if one is provided" do
|
26
|
+
ThinkingSphinx::AbstractAdapter.stub(:adapter_for_model => CustomAdapter)
|
27
|
+
CustomAdapter.should_receive(:new).and_return(stub('adapter'))
|
28
|
+
|
29
|
+
ThinkingSphinx::AbstractAdapter.detect(model)
|
30
|
+
end
|
31
|
+
|
21
32
|
it "raises an exception for other responses" do
|
22
33
|
ThinkingSphinx::AbstractAdapter.stub(:adapter_for_model => :sqlite)
|
23
34
|
|
@@ -68,6 +68,15 @@ describe ThinkingSphinx::Attribute do
|
|
68
68
|
|
69
69
|
attribute.to_select_sql.should == "CONCAT_WS(' ', IFNULL(`cricket_teams`.`name`, ''), IFNULL(`football_teams`.`name`, ''), IFNULL(`football_teams`.`league`, '')) AS `team`"
|
70
70
|
end
|
71
|
+
|
72
|
+
it "should return nil if polymorphic association data does not exist" do
|
73
|
+
attribute = ThinkingSphinx::Attribute.new(@source,
|
74
|
+
[ThinkingSphinx::Index::FauxColumn.new(:source, :id)],
|
75
|
+
:as => :source_id, :type => :integer
|
76
|
+
)
|
77
|
+
|
78
|
+
attribute.to_select_sql.should be_nil
|
79
|
+
end
|
71
80
|
end
|
72
81
|
|
73
82
|
describe '#is_many?' do
|
@@ -231,6 +231,23 @@ describe ThinkingSphinx::Configuration do
|
|
231
231
|
file.should_not match(/index alpha_core\s+\{\s+[^\}]*prefix_fields\s+=[^\}]*\}/m)
|
232
232
|
end
|
233
233
|
|
234
|
+
describe '#generate' do
|
235
|
+
let(:config) { ThinkingSphinx::Configuration.instance }
|
236
|
+
|
237
|
+
it "should set all sphinx_internal_id attributes to bigints if one is" do
|
238
|
+
config.reset
|
239
|
+
config.generate
|
240
|
+
|
241
|
+
config.configuration.indexes.each do |index|
|
242
|
+
next if index.is_a? Riddle::Configuration::DistributedIndex
|
243
|
+
|
244
|
+
index.sources.each do |source|
|
245
|
+
source.sql_attr_bigint.should include(:sphinx_internal_id)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
234
251
|
describe '#client' do
|
235
252
|
before :each do
|
236
253
|
@config = ThinkingSphinx::Configuration.instance
|
@@ -329,5 +329,19 @@ describe ThinkingSphinx::Facet do
|
|
329
329
|
@facet.value(alpha, {'cost' => 1093140480}).should == 10.5
|
330
330
|
end
|
331
331
|
end
|
332
|
+
|
333
|
+
context 'manual value source' do
|
334
|
+
let(:index) { ThinkingSphinx::Index.new(Alpha) }
|
335
|
+
let(:source) { ThinkingSphinx::Source.new(index) }
|
336
|
+
let(:column) { ThinkingSphinx::Index::FauxColumn.new('LOWER(name)') }
|
337
|
+
let(:field) { ThinkingSphinx::Field.new(source, column) }
|
338
|
+
let(:facet) { ThinkingSphinx::Facet.new(field, :name) }
|
339
|
+
|
340
|
+
it "should use the given value source to figure out the value" do
|
341
|
+
alpha = Alpha.new(:name => 'Foo')
|
342
|
+
|
343
|
+
facet.value(alpha, {'foo_facet' => 'foo'.to_crc32}).should == 'Foo'
|
344
|
+
end
|
345
|
+
end
|
332
346
|
end
|
333
347
|
end
|
@@ -44,6 +44,17 @@ describe ThinkingSphinx::Field do
|
|
44
44
|
@field.unique_name.should == "col_name"
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
describe '#to_select_sql' do
|
49
|
+
it "should return nil if polymorphic association data does not exist" do
|
50
|
+
field = ThinkingSphinx::Field.new(@source,
|
51
|
+
[ThinkingSphinx::Index::FauxColumn.new(:source, :name)],
|
52
|
+
:as => :source_name
|
53
|
+
)
|
54
|
+
|
55
|
+
field.to_select_sql.should be_nil
|
56
|
+
end
|
57
|
+
end
|
47
58
|
|
48
59
|
describe "prefixes method" do
|
49
60
|
it "should default to false" do
|
@@ -48,6 +48,10 @@ describe ThinkingSphinx::Source do
|
|
48
48
|
@source, ThinkingSphinx::Index::FauxColumn.new(:contacts, :id),
|
49
49
|
:as => :contact_ids, :source => :query
|
50
50
|
)
|
51
|
+
ThinkingSphinx::Attribute.new(
|
52
|
+
@source, ThinkingSphinx::Index::FauxColumn.new(:source, :id),
|
53
|
+
:as => :source_id, :type => :integer
|
54
|
+
)
|
51
55
|
|
52
56
|
ThinkingSphinx::Join.new(
|
53
57
|
@source, ThinkingSphinx::Index::FauxColumn.new(:links)
|
@@ -103,6 +107,12 @@ describe ThinkingSphinx::Source do
|
|
103
107
|
@riddle.sql_attr_timestamp.first.should == :birthday
|
104
108
|
end
|
105
109
|
|
110
|
+
it "should not include an attribute definition for polymorphic references without data" do
|
111
|
+
@riddle.sql_attr_uint.select { |uint|
|
112
|
+
uint == :source_id
|
113
|
+
}.should be_empty
|
114
|
+
end
|
115
|
+
|
106
116
|
it "should set Sphinx Source options" do
|
107
117
|
@riddle.sql_range_step.should == 1000
|
108
118
|
@riddle.sql_ranged_throttle.should == 100
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thinking-sphinx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 1.4.
|
9
|
+
- 2
|
10
|
+
version: 1.4.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Pat Allan
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-01-13 00:00:00 +11:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -51,12 +51,12 @@ dependencies:
|
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
hash:
|
54
|
+
hash: 27
|
55
55
|
segments:
|
56
56
|
- 1
|
57
57
|
- 2
|
58
|
-
-
|
59
|
-
version: 1.2.
|
58
|
+
- 2
|
59
|
+
version: 1.2.2
|
60
60
|
requirement: *id002
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
type: :runtime
|