thinking-sphinx 1.5.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/README.textile +15 -48
  2. data/VERSION +1 -0
  3. data/features/attribute_transformation.feature +7 -7
  4. data/features/attribute_updates.feature +16 -18
  5. data/features/deleting_instances.feature +13 -16
  6. data/features/excerpts.feature +0 -8
  7. data/features/facets.feature +19 -25
  8. data/features/handling_edits.feature +20 -25
  9. data/features/searching_across_models.feature +1 -1
  10. data/features/searching_by_index.feature +5 -6
  11. data/features/searching_by_model.feature +29 -29
  12. data/features/sphinx_scopes.feature +0 -26
  13. data/features/step_definitions/common_steps.rb +6 -18
  14. data/features/step_definitions/scope_steps.rb +0 -4
  15. data/features/step_definitions/search_steps.rb +4 -9
  16. data/features/support/env.rb +10 -3
  17. data/features/thinking_sphinx/db/fixtures/alphas.rb +10 -8
  18. data/features/thinking_sphinx/db/fixtures/cats.rb +1 -1
  19. data/features/thinking_sphinx/db/fixtures/dogs.rb +1 -1
  20. data/features/thinking_sphinx/db/fixtures/foxes.rb +1 -1
  21. data/features/thinking_sphinx/db/fixtures/people.rb +1 -1
  22. data/features/thinking_sphinx/db/fixtures/posts.rb +1 -5
  23. data/features/thinking_sphinx/db/migrations/create_posts.rb +0 -1
  24. data/features/thinking_sphinx/models/alpha.rb +0 -1
  25. data/features/thinking_sphinx/models/beta.rb +0 -5
  26. data/features/thinking_sphinx/models/developer.rb +1 -6
  27. data/features/thinking_sphinx/models/music.rb +1 -3
  28. data/features/thinking_sphinx/models/person.rb +1 -2
  29. data/features/thinking_sphinx/models/post.rb +0 -1
  30. data/lib/cucumber/thinking_sphinx/external_world.rb +4 -8
  31. data/lib/cucumber/thinking_sphinx/internal_world.rb +27 -36
  32. data/lib/thinking_sphinx.rb +60 -132
  33. data/lib/thinking_sphinx/active_record.rb +98 -124
  34. data/lib/thinking_sphinx/active_record/attribute_updates.rb +13 -17
  35. data/lib/thinking_sphinx/active_record/delta.rb +15 -21
  36. data/lib/thinking_sphinx/active_record/has_many_association.rb +23 -16
  37. data/lib/thinking_sphinx/active_record/scopes.rb +0 -18
  38. data/lib/thinking_sphinx/adapters/abstract_adapter.rb +15 -63
  39. data/lib/thinking_sphinx/adapters/mysql_adapter.rb +0 -4
  40. data/lib/thinking_sphinx/adapters/postgresql_adapter.rb +24 -65
  41. data/lib/thinking_sphinx/association.rb +11 -36
  42. data/lib/thinking_sphinx/attribute.rb +85 -92
  43. data/lib/thinking_sphinx/auto_version.rb +3 -21
  44. data/lib/thinking_sphinx/class_facet.rb +3 -8
  45. data/lib/thinking_sphinx/configuration.rb +58 -114
  46. data/lib/thinking_sphinx/context.rb +20 -22
  47. data/lib/thinking_sphinx/core/array.rb +13 -0
  48. data/lib/thinking_sphinx/deltas.rb +0 -2
  49. data/lib/thinking_sphinx/deltas/default_delta.rb +22 -18
  50. data/lib/thinking_sphinx/deploy/capistrano.rb +31 -30
  51. data/lib/thinking_sphinx/excerpter.rb +1 -2
  52. data/lib/thinking_sphinx/facet.rb +35 -45
  53. data/lib/thinking_sphinx/facet_search.rb +24 -58
  54. data/lib/thinking_sphinx/field.rb +0 -18
  55. data/lib/thinking_sphinx/index.rb +36 -38
  56. data/lib/thinking_sphinx/index/builder.rb +59 -74
  57. data/lib/thinking_sphinx/property.rb +45 -66
  58. data/lib/thinking_sphinx/railtie.rb +35 -0
  59. data/lib/thinking_sphinx/search.rb +250 -506
  60. data/lib/thinking_sphinx/source.rb +31 -50
  61. data/lib/thinking_sphinx/source/internal_properties.rb +3 -8
  62. data/lib/thinking_sphinx/source/sql.rb +31 -71
  63. data/lib/thinking_sphinx/tasks.rb +27 -48
  64. data/spec/thinking_sphinx/active_record/delta_spec.rb +41 -36
  65. data/spec/thinking_sphinx/active_record/has_many_association_spec.rb +0 -96
  66. data/spec/thinking_sphinx/active_record/scopes_spec.rb +29 -29
  67. data/spec/thinking_sphinx/active_record_spec.rb +169 -140
  68. data/spec/thinking_sphinx/association_spec.rb +2 -20
  69. data/spec/thinking_sphinx/attribute_spec.rb +97 -101
  70. data/spec/thinking_sphinx/auto_version_spec.rb +11 -75
  71. data/spec/thinking_sphinx/configuration_spec.rb +62 -63
  72. data/spec/thinking_sphinx/context_spec.rb +66 -66
  73. data/spec/thinking_sphinx/facet_search_spec.rb +99 -99
  74. data/spec/thinking_sphinx/facet_spec.rb +4 -30
  75. data/spec/thinking_sphinx/field_spec.rb +3 -17
  76. data/spec/thinking_sphinx/index/builder_spec.rb +132 -169
  77. data/spec/thinking_sphinx/index_spec.rb +39 -45
  78. data/spec/thinking_sphinx/search_methods_spec.rb +33 -37
  79. data/spec/thinking_sphinx/search_spec.rb +269 -491
  80. data/spec/thinking_sphinx/source_spec.rb +48 -62
  81. data/spec/thinking_sphinx_spec.rb +49 -49
  82. data/tasks/distribution.rb +46 -0
  83. data/tasks/testing.rb +74 -0
  84. metadata +123 -199
  85. data/features/field_sorting.feature +0 -18
  86. data/features/thinking_sphinx/db/.gitignore +0 -1
  87. data/features/thinking_sphinx/db/fixtures/post_keywords.txt +0 -1
  88. data/features/thinking_sphinx/models/andrew.rb +0 -17
  89. data/lib/thinking-sphinx.rb +0 -1
  90. data/lib/thinking_sphinx/active_record/has_many_association_with_scopes.rb +0 -21
  91. data/lib/thinking_sphinx/bundled_search.rb +0 -40
  92. data/lib/thinking_sphinx/connection.rb +0 -71
  93. data/lib/thinking_sphinx/deltas/delete_job.rb +0 -16
  94. data/lib/thinking_sphinx/deltas/index_job.rb +0 -17
  95. data/lib/thinking_sphinx/rails_additions.rb +0 -181
  96. data/spec/fixtures/data.sql +0 -32
  97. data/spec/fixtures/database.yml.default +0 -3
  98. data/spec/fixtures/models.rb +0 -161
  99. data/spec/fixtures/structure.sql +0 -146
  100. data/spec/spec_helper.rb +0 -54
  101. data/spec/sphinx_helper.rb +0 -67
  102. data/spec/thinking_sphinx/adapters/abstract_adapter_spec.rb +0 -163
  103. data/spec/thinking_sphinx/connection_spec.rb +0 -77
  104. data/spec/thinking_sphinx/rails_additions_spec.rb +0 -203
@@ -19,8 +19,6 @@ module ThinkingSphinx
19
19
  # - :sortable => true
20
20
  # - :infixes => true
21
21
  # - :prefixes => true
22
- # - :file => true
23
- # - :with => :attribute # or :wordcount
24
22
  #
25
23
  # Alias is only required in three circumstances: when there's
26
24
  # another attribute or field with the same name, when the column name is
@@ -60,8 +58,6 @@ module ThinkingSphinx
60
58
  @sortable = options[:sortable] || false
61
59
  @infixes = options[:infixes] || false
62
60
  @prefixes = options[:prefixes] || false
63
- @file = options[:file] || false
64
- @with = options[:with]
65
61
 
66
62
  source.fields << self
67
63
  end
@@ -73,8 +69,6 @@ module ThinkingSphinx
73
69
  # multiple data values (has_many or has_and_belongs_to_many associations).
74
70
  #
75
71
  def to_select_sql
76
- return nil unless available?
77
-
78
72
  clause = columns_with_prefixes.join(', ')
79
73
 
80
74
  clause = adapter.concatenate(clause) if concat_ws?
@@ -82,17 +76,5 @@ module ThinkingSphinx
82
76
 
83
77
  "#{clause} AS #{quote_column(unique_name)}"
84
78
  end
85
-
86
- def file?
87
- @file
88
- end
89
-
90
- def with_attribute?
91
- @with == :attribute
92
- end
93
-
94
- def with_wordcount?
95
- @with == :wordcount
96
- end
97
79
  end
98
80
  end
@@ -3,8 +3,8 @@ require 'thinking_sphinx/index/faux_column'
3
3
 
4
4
  module ThinkingSphinx
5
5
  class Index
6
- attr_accessor :name, :model, :sources, :delta_object, :additional_indices
7
-
6
+ attr_accessor :name, :model, :sources, :delta_object
7
+
8
8
  # Create a new index instance by passing in the model it is tied to, and
9
9
  # a block to build it with (optional but recommended). For documentation
10
10
  # on the syntax for inside the block, the Builder class is what you want.
@@ -13,9 +13,9 @@ module ThinkingSphinx
13
13
  #
14
14
  # Index.new(User) do
15
15
  # indexes login, email
16
- #
16
+ #
17
17
  # has created_at
18
- #
18
+ #
19
19
  # set_property :delta => true
20
20
  # end
21
21
  #
@@ -25,48 +25,47 @@ module ThinkingSphinx
25
25
  @sources = []
26
26
  @options = {}
27
27
  @delta_object = nil
28
- @additional_indices = []
29
28
  end
30
-
29
+
31
30
  def fields
32
31
  @sources.collect { |source| source.fields }.flatten
33
32
  end
34
-
33
+
35
34
  def attributes
36
35
  @sources.collect { |source| source.attributes }.flatten
37
36
  end
38
-
37
+
39
38
  def core_name
40
39
  "#{name}_core"
41
40
  end
42
-
41
+
43
42
  def delta_name
44
43
  "#{name}_delta"
45
44
  end
46
-
45
+
47
46
  def all_names
48
47
  names = [core_name]
49
48
  names << delta_name if delta?
50
-
49
+
51
50
  names
52
51
  end
53
-
52
+
54
53
  def self.name_for(model)
55
54
  model.name.underscore.tr(':/\\', '_')
56
55
  end
57
-
56
+
58
57
  def prefix_fields
59
58
  fields.select { |field| field.prefixes }
60
59
  end
61
-
60
+
62
61
  def infix_fields
63
62
  fields.select { |field| field.infixes }
64
63
  end
65
-
64
+
66
65
  def local_options
67
66
  @options
68
67
  end
69
-
68
+
70
69
  def options
71
70
  all_index_options = config.index_options.clone
72
71
  @options.keys.select { |key|
@@ -75,83 +74,82 @@ module ThinkingSphinx
75
74
  }.each { |key| all_index_options[key.to_sym] = @options[key] }
76
75
  all_index_options
77
76
  end
78
-
77
+
79
78
  def delta?
80
79
  !@delta_object.nil?
81
80
  end
82
-
81
+
83
82
  def to_riddle(offset)
84
83
  indexes = [to_riddle_for_core(offset)]
85
84
  indexes << to_riddle_for_delta(offset) if delta?
86
85
  indexes << to_riddle_for_distributed
87
86
  end
88
-
87
+
89
88
  private
90
-
89
+
91
90
  def adapter
92
91
  @adapter ||= @model.sphinx_database_adapter
93
92
  end
94
-
93
+
95
94
  def utf8?
96
95
  options[:charset_type] == "utf-8"
97
96
  end
98
-
97
+
99
98
  def sql_query_pre_for_delta
100
99
  [""]
101
100
  end
102
-
101
+
103
102
  def config
104
103
  @config ||= ThinkingSphinx::Configuration.instance
105
104
  end
106
-
105
+
107
106
  def to_riddle_for_core(offset)
108
107
  index = Riddle::Configuration::Index.new core_name
109
108
  index.path = File.join config.searchd_file_path, index.name
110
-
109
+
111
110
  set_configuration_options_for_indexes index
112
111
  set_field_settings_for_indexes index
113
-
112
+
114
113
  sources.each_with_index do |source, i|
115
114
  index.sources << source.to_riddle_for_core(offset, i)
116
115
  end
117
-
116
+
118
117
  index
119
118
  end
120
-
119
+
121
120
  def to_riddle_for_delta(offset)
122
121
  index = Riddle::Configuration::Index.new delta_name
123
122
  index.parent = core_name
124
123
  index.path = File.join config.searchd_file_path, index.name
125
-
124
+
126
125
  sources.each_with_index do |source, i|
127
126
  index.sources << source.to_riddle_for_delta(offset, i)
128
127
  end
129
-
128
+
130
129
  index
131
130
  end
132
-
131
+
133
132
  def to_riddle_for_distributed
134
133
  index = Riddle::Configuration::DistributedIndex.new name
135
- index.local_indices << core_name
136
- index.local_indices += additional_indices
137
- index.local_indices.unshift delta_name if delta?
134
+ index.local_indexes << core_name
135
+ index.local_indexes.unshift delta_name if delta?
138
136
  index
139
137
  end
140
-
138
+
141
139
  def set_configuration_options_for_indexes(index)
142
140
  config.index_options.each do |key, value|
143
141
  method = "#{key}=".to_sym
144
142
  index.send(method, value) if index.respond_to?(method)
145
143
  end
146
-
144
+
147
145
  options.each do |key, value|
148
146
  index.send("#{key}=".to_sym, value) if ThinkingSphinx::Configuration::IndexOptions.include?(key.to_s) && !value.nil?
149
147
  end
150
148
  end
151
-
149
+
152
150
  def set_field_settings_for_indexes(index)
153
151
  field_names = lambda { |field| field.unique_name.to_s }
154
-
152
+
155
153
  index.prefix_field_names += prefix_fields.collect(&field_names)
156
154
  index.infix_field_names += infix_fields.collect(&field_names)
157
155
  end
@@ -11,7 +11,7 @@ module ThinkingSphinx
11
11
  # your indexes. #where provides a method to add manual SQL conditions, and
12
12
  # set_property allows you to set some settings on a per-index basis. Check
13
13
  # out each method's documentation for better ideas of usage.
14
- #
14
+ #
15
15
  class Builder
16
16
  instance_methods.grep(/^[^_]/).each { |method|
17
17
  next if method.to_s == "instance_eval"
@@ -19,28 +19,28 @@ module ThinkingSphinx
19
19
  caller.grep(/irb.completion/).empty? ? method_missing(method) : super
20
20
  }
21
21
  }
22
-
22
+
23
23
  def self.generate(model, name = nil, &block)
24
24
  index = ThinkingSphinx::Index.new(model)
25
25
  index.name = name unless name.nil?
26
-
26
+
27
27
  Builder.new(index, &block) if block_given?
28
-
28
+
29
29
  index.delta_object = ThinkingSphinx::Deltas.parse index
30
30
  index
31
31
  end
32
-
32
+
33
33
  def initialize(index, &block)
34
34
  @index = index
35
35
  @explicit_source = false
36
-
36
+
37
37
  self.instance_eval &block
38
-
38
+
39
39
  if no_fields?
40
40
  raise "At least one field is necessary for an index"
41
41
  end
42
42
  end
43
-
43
+
44
44
  def define_source(&block)
45
45
  if @explicit_source
46
46
  @source = ThinkingSphinx::Source.new(@index)
@@ -48,15 +48,10 @@ module ThinkingSphinx
48
48
  else
49
49
  @explicit_source = true
50
50
  end
51
-
51
+
52
52
  self.instance_eval &block
53
53
  end
54
-
55
- def use_local_indices(*indexes)
56
- @index.additional_indices += indexes.map {|index_name| "#{index_name.to_s}_core"}
57
- end
58
- alias_method :use_local_index, :use_local_indices
59
-
54
+
60
55
  # This is how you add fields - the strings Sphinx looks at - to your
61
56
  # index. Technically, to use this method, you need to pass in some
62
57
  # columns and options - but there's some neat method_missing stuff
@@ -68,26 +63,26 @@ module ThinkingSphinx
68
63
  # field.
69
64
  #
70
65
  # Adding Single-Column Fields:
71
- #
66
+ #
72
67
  # You can use symbols or methods - and can chain methods together to
73
68
  # get access down the associations tree.
74
- #
69
+ #
75
70
  # indexes :id, :as => :my_id
76
71
  # indexes :name, :sortable => true
77
72
  # indexes first_name, last_name, :sortable => true
78
73
  # indexes users.posts.content, :as => :post_content
79
74
  # indexes users(:id), :as => :user_ids
80
75
  #
81
- # Keep in mind that if any keywords for Ruby methods - such as id or
76
+ # Keep in mind that if any keywords for Ruby methods - such as id or
82
77
  # name - clash with your column names, you need to use the symbol
83
78
  # version (see the first, second and last examples above).
84
79
  #
85
80
  # If you specify multiple columns (example #2), a field will be created
86
81
  # for each. Don't use the :as option in this case. If you want to merge
87
82
  # those columns together, continue reading.
88
- #
83
+ #
89
84
  # Adding Multi-Column Fields:
90
- #
85
+ #
91
86
  # indexes [first_name, last_name], :as => :name
92
87
  # indexes [location, parent.location], :as => :location
93
88
  #
@@ -95,7 +90,7 @@ module ThinkingSphinx
95
90
  # them in an Array, as shown by the above examples. There's no
96
91
  # limitations on whether they're symbols or methods or what level of
97
92
  # associations they come from.
98
- #
93
+ #
99
94
  # Adding SQL Fragment Fields
100
95
  #
101
96
  # You can also define a field using an SQL fragment, useful for when
@@ -107,37 +102,37 @@ module ThinkingSphinx
107
102
  options = args.extract_options!
108
103
  args.each do |columns|
109
104
  field = Field.new(source, FauxColumn.coerce(columns), options)
110
-
105
+
111
106
  add_sort_attribute field, options if field.sortable
112
107
  add_facet_attribute field, options if field.faceted
113
108
  end
114
109
  end
115
-
110
+
116
111
  # This is the method to add attributes to your index (hence why it is
117
112
  # aliased as 'attribute'). The syntax is the same as #indexes, so use
118
113
  # that as starting point, but keep in mind the following points.
119
- #
114
+ #
120
115
  # An attribute can have an alias (the :as option), but it is always
121
116
  # sortable - so you don't need to explicitly request that. You _can_
122
117
  # specify the data type of the attribute (the :type option), but the
123
118
  # code's pretty good at figuring that out itself from peering into the
124
119
  # database.
125
- #
120
+ #
126
121
  # Attributes are limited to the following types: integers, floats,
127
122
  # datetimes (converted to timestamps), booleans, strings and MVAs
128
123
  # (:multi). Don't forget that Sphinx converts string attributes to
129
124
  # integers, which are useful for sorting, but that's about it.
130
- #
125
+ #
131
126
  # Collection of integers are known as multi-value attributes (MVAs).
132
127
  # Generally these would be through a has_many relationship, like in this
133
128
  # example:
134
- #
129
+ #
135
130
  # has posts(:id), :as => :post_ids
136
- #
131
+ #
137
132
  # This allows you to filter on any of the values tied to a specific
138
133
  # record. Might be best to read through the Sphinx documentation to get
139
134
  # a better idea of that though.
140
- #
135
+ #
141
136
  # Adding SQL Fragment Attributes
142
137
  #
143
138
  # You can also define an attribute using an SQL fragment, useful for
@@ -145,68 +140,68 @@ module ThinkingSphinx
145
140
  # the type of the attribute though:
146
141
  #
147
142
  # has "age < 18", :as => :minor, :type => :boolean
148
- #
143
+ #
149
144
  # If you're creating attributes for latitude and longitude, don't
150
145
  # forget that Sphinx expects these values to be in radians.
151
- #
146
+ #
152
147
  def has(*args)
153
148
  options = args.extract_options!
154
149
  args.each do |columns|
155
150
  attribute = Attribute.new(source, FauxColumn.coerce(columns), options)
156
-
151
+
157
152
  add_facet_attribute attribute, options if attribute.faceted
158
153
  end
159
154
  end
160
-
155
+
161
156
  def facet(*args)
162
157
  options = args.extract_options!
163
158
  options[:facet] = true
164
-
159
+
165
160
  args.each do |columns|
166
161
  attribute = Attribute.new(source, FauxColumn.coerce(columns), options)
167
-
162
+
168
163
  add_facet_attribute attribute, options
169
164
  end
170
165
  end
171
-
166
+
172
167
  def join(*args)
173
168
  args.each do |association|
174
169
  Join.new(source, association)
175
170
  end
176
171
  end
177
-
172
+
178
173
  # Use this method to add some manual SQL conditions for your index
179
174
  # request. You can pass in as many strings as you like, they'll get
180
175
  # joined together with ANDs later on.
181
- #
176
+ #
182
177
  # where "user_id = 10"
183
178
  # where "parent_type = 'Article'", "created_at < NOW()"
184
- #
179
+ #
185
180
  def where(*args)
186
181
  source.conditions += args
187
182
  end
188
-
183
+
189
184
  # Use this method to add some manual SQL strings to the GROUP BY
190
185
  # clause. You can pass in as many strings as you'd like, they'll get
191
186
  # joined together with commas later on.
192
- #
187
+ #
193
188
  # group_by "lat", "lng"
194
- #
189
+ #
195
190
  def group_by(*args)
196
191
  source.groupings += args
197
192
  end
198
-
193
+
199
194
  # This is what to use to set properties on the index. Chief amongst
200
195
  # those is the delta property - to allow automatic updates to your
201
196
  # indexes as new models are added and edited - but also you can
202
197
  # define search-related properties which will be the defaults for all
203
198
  # searches on the model.
204
- #
199
+ #
205
200
  # set_property :delta => true
206
201
  # set_property :field_weights => {"name" => 100}
207
202
  # set_property :order => "name ASC"
208
203
  # set_property :select => 'name'
209
- #
204
+ #
210
205
  # Also, the following two properties are particularly relevant for
211
206
  # geo-location searching - latitude_attr and longitude_attr. If your
212
207
  # attributes for these two values are named something other than
@@ -215,59 +210,49 @@ module ThinkingSphinx
215
210
  # geo-related search.
216
211
  #
217
212
  # set_property :latitude_attr => "lt", :longitude_attr => "lg"
218
- #
213
+ #
219
214
  # Please don't forget to add a boolean field named 'delta' to your
220
215
  # model's database table if enabling the delta index for it.
221
216
  # Valid options for the delta property are:
222
- #
217
+ #
223
218
  # true
224
219
  # false
225
220
  # :default
226
221
  # :delayed
227
222
  # :datetime
228
- #
229
- # You can also extend ThinkingSphinx::Deltas::DefaultDelta to implement
223
+ #
224
+ # You can also extend ThinkingSphinx::Deltas::DefaultDelta to implement
230
225
  # your own handling for delta indexing.
231
- #
226
+ #
232
227
  def set_property(*args)
233
228
  options = args.extract_options!
234
229
  options.each do |key, value|
235
230
  set_single_property key, value
236
231
  end
237
-
232
+
238
233
  set_single_property args[0], args[1] if args.length == 2
239
234
  end
240
235
  alias_method :set_properties, :set_property
241
-
236
+
242
237
  # Handles the generation of new columns for the field and attribute
243
238
  # definitions.
244
- #
239
+ #
245
240
  def method_missing(method, *args)
246
241
  FauxColumn.new(method, *args)
247
242
  end
248
-
243
+
249
244
  # A method to allow adding fields from associations which have names
250
245
  # that clash with method names in the Builder class (ie: properties,
251
246
  # fields, attributes).
252
- #
247
+ #
253
248
  # Example: indexes assoc(:properties).column
254
- #
249
+ #
255
250
  def assoc(assoc, *args)
256
251
  FauxColumn.new(assoc, *args)
257
252
  end
258
-
259
- # Use this method to generate SQL for your attributes, conditions, etc.
260
- # You can pass in as whatever ActiveRecord::Base.sanitize_sql accepts.
261
- #
262
- # where sanitize_sql(["active = ?", true])
263
- # #=> WHERE active = 1
264
- #
265
- def sanitize_sql(*args)
266
- @index.model.send(:sanitize_sql, *args)
267
- end
268
-
253
+
269
254
  private
270
-
255
+
271
256
  def source
272
257
  @source ||= begin
273
258
  source = ThinkingSphinx::Source.new(@index)
@@ -275,7 +260,7 @@ module ThinkingSphinx
275
260
  source
276
261
  end
277
262
  end
278
-
263
+
279
264
  def set_single_property(key, value)
280
265
  source_options = ThinkingSphinx::Configuration::SourceOptions
281
266
  if source_options.include?(key.to_s)
@@ -284,19 +269,19 @@ module ThinkingSphinx
284
269
  @index.local_options.merge! key => value
285
270
  end
286
271
  end
287
-
272
+
288
273
  def add_sort_attribute(field, options)
289
274
  add_internal_attribute field, options, "_sort"
290
275
  end
291
-
276
+
292
277
  def add_facet_attribute(property, options)
293
278
  add_internal_attribute property, options, "_facet", true
294
279
  @index.model.sphinx_facets << property.to_facet
295
280
  end
296
-
281
+
297
282
  def add_internal_attribute(property, options, suffix, crc = false)
298
283
  return unless ThinkingSphinx::Facet.translate?(property)
299
-
284
+
300
285
  Attribute.new(source,
301
286
  property.columns.collect { |col| col.clone },
302
287
  options.merge(
@@ -306,7 +291,7 @@ module ThinkingSphinx
306
291
  ).except(:facet)
307
292
  )
308
293
  end
309
-
294
+
310
295
  def no_fields?
311
296
  @index.sources.empty? || @index.sources.any? { |source|
312
297
  source.fields.length == 0