summaryrefslogtreecommitdiff
path: root/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb
diff options
context:
space:
mode:
authorUser <hukl@cccms.ccc.de>2011-02-10 14:23:36 +0100
committerUser <hukl@cccms.ccc.de>2011-02-10 14:23:36 +0100
commit384b187e9e067ddf2bb4d5fad0c2deaf96f69c89 (patch)
treecf743f377d3e2e28a31ae0359d95f37beba82cc3 /vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb
parent3d0de09cf94cee6233b36a7f5ce20d5059854acc (diff)
parentcec2b1e2881db0000b2a09029154bea0fc62ade3 (diff)
Merge branch 'master' of ssh://svn.medienhaus.udk-berlin.de/usr/local/git/cccms
Diffstat (limited to 'vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb')
-rw-r--r--vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb264
1 files changed, 0 insertions, 264 deletions
diff --git a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb b/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb
deleted file mode 100644
index dbd2ba0..0000000
--- a/vendor/plugins/thinking-sphinx/lib/thinking_sphinx/index/builder.rb
+++ /dev/null
@@ -1,264 +0,0 @@
1module ThinkingSphinx
2 class Index
3 # The Builder class is the core for the index definition block processing.
4 # There are four methods you really need to pay attention to:
5 # - indexes (aliased to includes and attribute)
6 # - has (aliased to attribute)
7 # - where
8 # - set_property (aliased to set_properties)
9 #
10 # The first two of these methods allow you to define what data makes up
11 # your indexes. #where provides a method to add manual SQL conditions, and
12 # set_property allows you to set some settings on a per-index basis. Check
13 # out each method's documentation for better ideas of usage.
14 #
15 class Builder
16 class << self
17 # No idea where this is coming from - haven't found it in any ruby or
18 # rails documentation. It's not needed though, so it gets undef'd.
19 # Hopefully the list of methods that get in the way doesn't get too
20 # long.
21 HiddenMethods = [:parent, :name, :id, :type].each { |method|
22 define_method(method) {
23 caller.grep(/irb.completion/).empty? ? method_missing(method) : super
24 }
25 }
26
27 attr_accessor :fields, :attributes, :properties, :conditions,
28 :groupings
29
30 # Set up all the collections. Consider this the equivalent of an
31 # instance's initialize method.
32 #
33 def setup
34 @fields = []
35 @attributes = []
36 @properties = {}
37 @conditions = []
38 @groupings = []
39 end
40
41 # This is how you add fields - the strings Sphinx looks at - to your
42 # index. Technically, to use this method, you need to pass in some
43 # columns and options - but there's some neat method_missing stuff
44 # happening, so lets stick to the expected syntax within a define_index
45 # block.
46 #
47 # Expected options are :as, which points to a column alias in symbol
48 # form, and :sortable, which indicates whether you want to sort by this
49 # field.
50 #
51 # Adding Single-Column Fields:
52 #
53 # You can use symbols or methods - and can chain methods together to
54 # get access down the associations tree.
55 #
56 # indexes :id, :as => :my_id
57 # indexes :name, :sortable => true
58 # indexes first_name, last_name, :sortable => true
59 # indexes users.posts.content, :as => :post_content
60 # indexes users(:id), :as => :user_ids
61 #
62 # Keep in mind that if any keywords for Ruby methods - such as id or
63 # name - clash with your column names, you need to use the symbol
64 # version (see the first, second and last examples above).
65 #
66 # If you specify multiple columns (example #2), a field will be created
67 # for each. Don't use the :as option in this case. If you want to merge
68 # those columns together, continue reading.
69 #
70 # Adding Multi-Column Fields:
71 #
72 # indexes [first_name, last_name], :as => :name
73 # indexes [location, parent.location], :as => :location
74 #
75 # To combine multiple columns into a single field, you need to wrap
76 # them in an Array, as shown by the above examples. There's no
77 # limitations on whether they're symbols or methods or what level of
78 # associations they come from.
79 #
80 # Adding SQL Fragment Fields
81 #
82 # You can also define a field using an SQL fragment, useful for when
83 # you would like to index a calculated value.
84 #
85 # indexes "age < 18", :as => :minor
86 #
87 def indexes(*args)
88 options = args.extract_options!
89 args.each do |columns|
90 field = Field.new(FauxColumn.coerce(columns), options)
91 fields << field
92
93 add_sort_attribute field, options if field.sortable
94 add_facet_attribute field, options if field.faceted
95 end
96 end
97 alias_method :field, :indexes
98 alias_method :includes, :indexes
99
100 # This is the method to add attributes to your index (hence why it is
101 # aliased as 'attribute'). The syntax is the same as #indexes, so use
102 # that as starting point, but keep in mind the following points.
103 #
104 # An attribute can have an alias (the :as option), but it is always
105 # sortable - so you don't need to explicitly request that. You _can_
106 # specify the data type of the attribute (the :type option), but the
107 # code's pretty good at figuring that out itself from peering into the
108 # database.
109 #
110 # Attributes are limited to the following types: integers, floats,
111 # datetimes (converted to timestamps), booleans and strings. Don't
112 # forget that Sphinx converts string attributes to integers, which are
113 # useful for sorting, but that's about it.
114 #
115 # You can also have a collection of integers for multi-value attributes
116 # (MVAs). Generally these would be through a has_many relationship,
117 # like in this example:
118 #
119 # has posts(:id), :as => :post_ids
120 #
121 # This allows you to filter on any of the values tied to a specific
122 # record. Might be best to read through the Sphinx documentation to get
123 # a better idea of that though.
124 #
125 # Adding SQL Fragment Attributes
126 #
127 # You can also define an attribute using an SQL fragment, useful for
128 # when you would like to index a calculated value. Don't forget to set
129 # the type of the attribute though:
130 #
131 # has "age < 18", :as => :minor, :type => :boolean
132 #
133 # If you're creating attributes for latitude and longitude, don't
134 # forget that Sphinx expects these values to be in radians.
135 #
136 def has(*args)
137 options = args.extract_options!
138 args.each do |columns|
139 attribute = Attribute.new(FauxColumn.coerce(columns), options)
140 attributes << attribute
141
142 add_facet_attribute attribute, options if attribute.faceted
143 end
144 end
145 alias_method :attribute, :has
146
147 def facet(*args)
148 options = args.extract_options!
149 options[:facet] = true
150
151 args.each do |columns|
152 attribute = Attribute.new(FauxColumn.coerce(columns), options)
153 attributes << attribute
154
155 add_facet_attribute attribute, options
156 end
157 end
158
159 # Use this method to add some manual SQL conditions for your index
160 # request. You can pass in as many strings as you like, they'll get
161 # joined together with ANDs later on.
162 #
163 # where "user_id = 10"
164 # where "parent_type = 'Article'", "created_at < NOW()"
165 #
166 def where(*args)
167 @conditions += args
168 end
169
170 # Use this method to add some manual SQL strings to the GROUP BY
171 # clause. You can pass in as many strings as you'd like, they'll get
172 # joined together with commas later on.
173 #
174 # group_by "lat", "lng"
175 #
176 def group_by(*args)
177 @groupings += args
178 end
179
180 # This is what to use to set properties on the index. Chief amongst
181 # those is the delta property - to allow automatic updates to your
182 # indexes as new models are added and edited - but also you can
183 # define search-related properties which will be the defaults for all
184 # searches on the model.
185 #
186 # set_property :delta => true
187 # set_property :field_weights => {"name" => 100}
188 # set_property :order => "name ASC"
189 # set_property :include => :picture
190 # set_property :select => 'name'
191 #
192 # Also, the following two properties are particularly relevant for
193 # geo-location searching - latitude_attr and longitude_attr. If your
194 # attributes for these two values are named something other than
195 # lat/latitude or lon/long/longitude, you can dictate what they are
196 # when defining the index, so you don't need to specify them for every
197 # geo-related search.
198 #
199 # set_property :latitude_attr => "lt", :longitude_attr => "lg"
200 #
201 # Please don't forget to add a boolean field named 'delta' to your
202 # model's database table if enabling the delta index for it.
203 # Valid options for the delta property are:
204 #
205 # true
206 # false
207 # :default
208 # :delayed
209 # :datetime
210 #
211 # You can also extend ThinkingSphinx::Deltas::DefaultDelta to implement
212 # your own handling for delta indexing.
213
214 def set_property(*args)
215 options = args.extract_options!
216 if options.empty?
217 @properties[args[0]] = args[1]
218 else
219 @properties.merge!(options)
220 end
221 end
222 alias_method :set_properties, :set_property
223
224 # Handles the generation of new columns for the field and attribute
225 # definitions.
226 #
227 def method_missing(method, *args)
228 FauxColumn.new(method, *args)
229 end
230
231 # A method to allow adding fields from associations which have names
232 # that clash with method names in the Builder class (ie: properties,
233 # fields, attributes).
234 #
235 # Example: indexes assoc(:properties).column
236 #
237 def assoc(assoc, *args)
238 FauxColumn.new(assoc, *args)
239 end
240
241 private
242
243 def add_sort_attribute(field, options)
244 add_internal_attribute field, options, "_sort"
245 end
246
247 def add_facet_attribute(resource, options)
248 add_internal_attribute resource, options, "_facet", true
249 end
250
251 def add_internal_attribute(resource, options, suffix, crc = false)
252 @attributes << Attribute.new(
253 resource.columns.collect { |col| col.clone },
254 options.merge(
255 :type => resource.is_a?(Field) ? :string : nil,
256 :as => resource.unique_name.to_s.concat(suffix).to_sym,
257 :crc => crc
258 ).except(:facet)
259 )
260 end
261 end
262 end
263 end
264end