ultrasphinx 1.6 → 1.6.7
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +5 -1
- data/Manifest +47 -7
- data/README +4 -4
- data/TODO +1 -0
- data/examples/default.base +6 -2
- data/lib/ultrasphinx.rb +1 -1
- data/lib/ultrasphinx/configure.rb +53 -28
- data/lib/ultrasphinx/fields.rb +16 -13
- data/lib/ultrasphinx/postgresql/concat_ws.sql +35 -0
- data/lib/ultrasphinx/postgresql/crc32.sql +7 -0
- data/lib/ultrasphinx/postgresql/group_concat.sql +25 -0
- data/lib/ultrasphinx/{hex_to_int.sql → postgresql/hex_to_int.sql} +0 -0
- data/lib/ultrasphinx/postgresql/language.sql +1 -0
- data/lib/ultrasphinx/postgresql/unix_timestamp.sql +12 -0
- data/lib/ultrasphinx/search/internals.rb +42 -16
- data/lib/ultrasphinx/ultrasphinx.rb +23 -12
- data/test/integration/app/app/models/person/user.rb +1 -1
- data/test/integration/app/config/database.yml +9 -13
- data/test/integration/app/config/ultrasphinx/development.conf +6 -6
- data/test/integration/app/config/ultrasphinx/development.conf.canonical +6 -6
- data/test/integration/app/db/schema.rb +9 -2
- data/test/integration/search_test.rb +16 -6
- data/test/setup.rb +5 -1
- data/test/ts.multi +2 -0
- data/ultrasphinx.gemspec +5 -5
- data/vendor/riddle/{MIT-LICENSE → MIT-LICENCE} +0 -0
- data/vendor/riddle/README +60 -0
- data/vendor/riddle/Rakefile +25 -0
- data/vendor/riddle/{riddle.rb → lib/riddle.rb} +3 -0
- data/vendor/riddle/{riddle → lib/riddle}/client.rb +73 -4
- data/vendor/riddle/{riddle → lib/riddle}/client/filter.rb +0 -0
- data/vendor/riddle/{riddle → lib/riddle}/client/message.rb +2 -0
- data/vendor/riddle/{riddle → lib/riddle}/client/response.rb +0 -0
- data/vendor/riddle/spec/fixtures/data/anchor.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/any.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/boolean.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/distinct.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter_array.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter_array_exclude.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter_floats.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter_floats_exclude.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter_floats_range.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter_range.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/filter_range_exclude.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/group.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/index.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/phrase.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/simple.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/sort.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/update_simple.bin +0 -0
- data/vendor/riddle/spec/fixtures/data/weights.bin +0 -0
- data/vendor/riddle/spec/fixtures/sphinx/configuration.erb +38 -0
- data/vendor/riddle/spec/fixtures/sql/conf.example.yml +3 -0
- data/vendor/riddle/spec/fixtures/sql/data.sql +25000 -0
- data/vendor/riddle/spec/fixtures/sql/structure.sql +16 -0
- data/vendor/riddle/spec/functional/excerpt_spec.rb +102 -0
- data/vendor/riddle/spec/functional/search_spec.rb +69 -0
- data/vendor/riddle/spec/functional/update_spec.rb +41 -0
- data/vendor/riddle/spec/spec_helper.rb +25 -0
- data/vendor/riddle/spec/sphinx_helper.rb +91 -0
- data/vendor/riddle/spec/unit/client_spec.rb +140 -0
- data/vendor/riddle/spec/unit/filter_spec.rb +33 -0
- data/vendor/riddle/spec/unit/message_spec.rb +63 -0
- data/vendor/riddle/spec/unit/response_spec.rb +64 -0
- metadata +95 -55
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
v1.6.7. Fix GROUP_CONCAT aggregate problem. Discourage enable_star in default.base. Allow faceting on includes.
|
3
|
+
|
4
|
+
v1.6.6. Only use DISTINCT when necessary to improve indexing speed.
|
5
|
+
|
6
|
+
v1.6.5. Many PostgreSQL improvements.
|
3
7
|
|
4
8
|
v1.6. API changes! Drop Sphinx 0.9.7 compatibility; switch to Pat Allan's 0.9.8 client plugin; remove legacy keynames; fix string sorting bug; improve error handling.
|
5
9
|
|
data/Manifest
CHANGED
@@ -6,8 +6,13 @@ lib/ultrasphinx/autoload.rb
|
|
6
6
|
lib/ultrasphinx/configure.rb
|
7
7
|
lib/ultrasphinx/core_extensions.rb
|
8
8
|
lib/ultrasphinx/fields.rb
|
9
|
-
lib/ultrasphinx/hex_to_int.sql
|
10
9
|
lib/ultrasphinx/is_indexed.rb
|
10
|
+
lib/ultrasphinx/postgresql/concat_ws.sql
|
11
|
+
lib/ultrasphinx/postgresql/crc32.sql
|
12
|
+
lib/ultrasphinx/postgresql/group_concat.sql
|
13
|
+
lib/ultrasphinx/postgresql/hex_to_int.sql
|
14
|
+
lib/ultrasphinx/postgresql/language.sql
|
15
|
+
lib/ultrasphinx/postgresql/unix_timestamp.sql
|
11
16
|
lib/ultrasphinx/search/internals.rb
|
12
17
|
lib/ultrasphinx/search/parser.rb
|
13
18
|
lib/ultrasphinx/search.rb
|
@@ -124,12 +129,47 @@ test/integration/spell_test.rb
|
|
124
129
|
test/setup.rb
|
125
130
|
test/test_all.rb
|
126
131
|
test/test_helper.rb
|
132
|
+
test/ts.multi
|
127
133
|
test/unit/parser_test.rb
|
128
134
|
TODO
|
129
|
-
vendor/riddle/
|
130
|
-
vendor/riddle/riddle/client/
|
131
|
-
vendor/riddle/riddle/client/
|
132
|
-
vendor/riddle/riddle/client
|
133
|
-
vendor/riddle/riddle
|
134
|
-
vendor/riddle/
|
135
|
+
vendor/riddle/lib/riddle/client/filter.rb
|
136
|
+
vendor/riddle/lib/riddle/client/message.rb
|
137
|
+
vendor/riddle/lib/riddle/client/response.rb
|
138
|
+
vendor/riddle/lib/riddle/client.rb
|
139
|
+
vendor/riddle/lib/riddle.rb
|
140
|
+
vendor/riddle/MIT-LICENCE
|
141
|
+
vendor/riddle/Rakefile
|
142
|
+
vendor/riddle/README
|
143
|
+
vendor/riddle/spec/fixtures/data/anchor.bin
|
144
|
+
vendor/riddle/spec/fixtures/data/any.bin
|
145
|
+
vendor/riddle/spec/fixtures/data/boolean.bin
|
146
|
+
vendor/riddle/spec/fixtures/data/distinct.bin
|
147
|
+
vendor/riddle/spec/fixtures/data/filter.bin
|
148
|
+
vendor/riddle/spec/fixtures/data/filter_array.bin
|
149
|
+
vendor/riddle/spec/fixtures/data/filter_array_exclude.bin
|
150
|
+
vendor/riddle/spec/fixtures/data/filter_floats.bin
|
151
|
+
vendor/riddle/spec/fixtures/data/filter_floats_exclude.bin
|
152
|
+
vendor/riddle/spec/fixtures/data/filter_floats_range.bin
|
153
|
+
vendor/riddle/spec/fixtures/data/filter_range.bin
|
154
|
+
vendor/riddle/spec/fixtures/data/filter_range_exclude.bin
|
155
|
+
vendor/riddle/spec/fixtures/data/group.bin
|
156
|
+
vendor/riddle/spec/fixtures/data/index.bin
|
157
|
+
vendor/riddle/spec/fixtures/data/phrase.bin
|
158
|
+
vendor/riddle/spec/fixtures/data/simple.bin
|
159
|
+
vendor/riddle/spec/fixtures/data/sort.bin
|
160
|
+
vendor/riddle/spec/fixtures/data/update_simple.bin
|
161
|
+
vendor/riddle/spec/fixtures/data/weights.bin
|
162
|
+
vendor/riddle/spec/fixtures/sphinx/configuration.erb
|
163
|
+
vendor/riddle/spec/fixtures/sql/conf.example.yml
|
164
|
+
vendor/riddle/spec/fixtures/sql/data.sql
|
165
|
+
vendor/riddle/spec/fixtures/sql/structure.sql
|
166
|
+
vendor/riddle/spec/functional/excerpt_spec.rb
|
167
|
+
vendor/riddle/spec/functional/search_spec.rb
|
168
|
+
vendor/riddle/spec/functional/update_spec.rb
|
169
|
+
vendor/riddle/spec/spec_helper.rb
|
170
|
+
vendor/riddle/spec/sphinx_helper.rb
|
171
|
+
vendor/riddle/spec/unit/client_spec.rb
|
172
|
+
vendor/riddle/spec/unit/filter_spec.rb
|
173
|
+
vendor/riddle/spec/unit/message_spec.rb
|
174
|
+
vendor/riddle/spec/unit/response_spec.rb
|
135
175
|
vendor/will_paginate/LICENSE
|
data/README
CHANGED
@@ -5,14 +5,14 @@ Ruby on Rails configurator and client to the Sphinx full text search engine.
|
|
5
5
|
|
6
6
|
== License
|
7
7
|
|
8
|
-
Copyright 2007 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Some portions copyright Pat Allan, distributed under the MIT license, and used with permission. Some portions copyright PJ Hyett and Mislav Marohnić, distributed under the MIT license, and used with permission.
|
8
|
+
Copyright 2007 Cloudburst, LLC. Licensed under the AFL 3. See the included LICENSE file. Some portions copyright Pat Allan, distributed under the MIT license, and used with permission. Some portions copyright PJ Hyett and Mislav Marohnić, distributed under the MIT license, and used with permission.
|
9
9
|
|
10
10
|
The public certificate for the gem is at http://rubyforge.org/frs/download.php/25331/evan_weaver-original-public_cert.pem.
|
11
11
|
|
12
12
|
== Requirements
|
13
13
|
|
14
14
|
* MySQL (or Postgres, experimental)
|
15
|
-
* Sphinx 0.9.8-dev
|
15
|
+
* Sphinx 0.9.8-dev r871 or greater
|
16
16
|
* Rails 1.2.3 or greater
|
17
17
|
|
18
18
|
== Features
|
@@ -33,7 +33,7 @@ Good Rails integration:
|
|
33
33
|
* <tt>will_paginate</tt> compatibility
|
34
34
|
* query spellcheck
|
35
35
|
* Google-style query parser
|
36
|
-
*
|
36
|
+
* error recovery
|
37
37
|
* multiple deployment environments
|
38
38
|
* comprehensive Rake tasks
|
39
39
|
|
@@ -43,7 +43,7 @@ And some other things.
|
|
43
43
|
|
44
44
|
== Installation
|
45
45
|
|
46
|
-
First,
|
46
|
+
First, install Sphinx itself. Get the 0.9.8 development snapshot (http://www.sphinxsearch.com), then run <tt>./configure</tt>, <tt>make</tt>, and <tt>sudo make install</tt>. Make sure to set your <tt>./configure</tt> flags : <tt>--prefix</tt> if necessary, and also <tt>--with-pgsql</tt> if you need Postgres support.
|
47
47
|
|
48
48
|
You also need the <tt>chronic</tt> gem:
|
49
49
|
sudo gem install chronic
|
data/TODO
CHANGED
data/examples/default.base
CHANGED
@@ -39,7 +39,7 @@ client
|
|
39
39
|
source
|
40
40
|
{
|
41
41
|
# Individual SQL source options
|
42
|
-
sql_range_step =
|
42
|
+
sql_range_step = 5000
|
43
43
|
strip_html = 0
|
44
44
|
index_html_attrs =
|
45
45
|
sql_query_post =
|
@@ -53,7 +53,11 @@ index
|
|
53
53
|
morphology = stem_en
|
54
54
|
stopwords = # /path/to/stopwords.txt
|
55
55
|
min_word_len = 1
|
56
|
-
|
56
|
+
|
57
|
+
# Enable these if you need wildcard searching. They will slow down indexing significantly.
|
58
|
+
# min_infix_len = 1
|
59
|
+
# enable_star = 1
|
60
|
+
|
57
61
|
charset_type = utf-8 # or sbcs (Single Byte Character Set)
|
58
62
|
charset_table = 0..9, A..Z->a..z, -, _, ., &, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F,U+C5->U+E5, U+E5, U+C4->U+E4, U+E4, U+D6->U+F6, U+F6, U+16B, U+0c1->a, U+0c4->a, U+0c9->e, U+0cd->i, U+0d3->o, U+0d4->o, U+0da->u, U+0dd->y, U+0e1->a, U+0e4->a, U+0e9->e, U+0ed->i, U+0f3->o, U+0f4->o, U+0fa->u, U+0fd->y, U+104->U+105, U+105, U+106->U+107, U+10c->c, U+10d->c, U+10e->d, U+10f->d, U+116->U+117, U+117, U+118->U+119, U+11a->e, U+11b->e, U+12E->U+12F, U+12F, U+139->l, U+13a->l, U+13d->l, U+13e->l, U+141->U+142, U+142, U+143->U+144, U+144,U+147->n, U+148->n, U+154->r, U+155->r, U+158->r, U+159->r, U+15A->U+15B, U+15B, U+160->s, U+160->U+161, U+161->s, U+164->t, U+165->t, U+16A->U+16B, U+16B, U+16e->u, U+16f->u, U+172->U+173, U+173, U+179->U+17A, U+17A, U+17B->U+17C, U+17C, U+17d->z, U+17e->z,
|
59
63
|
}
|
data/lib/ultrasphinx.rb
CHANGED
@@ -72,7 +72,7 @@ module Ultrasphinx
|
|
72
72
|
|
73
73
|
|
74
74
|
def setup_source_database(klass)
|
75
|
-
#
|
75
|
+
# Supporting Postgres now
|
76
76
|
connection_settings = klass.connection.instance_variable_get("@config")
|
77
77
|
|
78
78
|
adapter_defaults = ADAPTER_DEFAULTS[ADAPTER]
|
@@ -95,7 +95,7 @@ module Ultrasphinx
|
|
95
95
|
"(#{klass.table_name}.#{klass.primary_key} * #{MODEL_CONFIGURATION.size} + #{class_id}) AS id",
|
96
96
|
"#{class_id} AS class_id", "'#{klass.name}' AS class"]
|
97
97
|
remaining_columns = fields.types.keys - ["class", "class_id"]
|
98
|
-
[column_strings, [], condition_strings, remaining_columns]
|
98
|
+
[column_strings, [], condition_strings, [], false, remaining_columns]
|
99
99
|
end
|
100
100
|
|
101
101
|
|
@@ -111,15 +111,21 @@ module Ultrasphinx
|
|
111
111
|
|
112
112
|
def build_source(fields, model, options, class_id, klass, source, groups)
|
113
113
|
|
114
|
-
column_strings, join_strings, condition_strings, remaining_columns =
|
115
|
-
setup_source_arrays(
|
114
|
+
column_strings, join_strings, condition_strings, group_bys, use_distinct, remaining_columns =
|
115
|
+
setup_source_arrays(
|
116
|
+
klass, fields, class_id, options['conditions'])
|
116
117
|
|
117
|
-
column_strings, join_strings, remaining_columns =
|
118
|
-
build_regular_fields(
|
119
|
-
|
120
|
-
|
121
|
-
column_strings, join_strings, remaining_columns =
|
122
|
-
|
118
|
+
column_strings, join_strings, group_bys, remaining_columns =
|
119
|
+
build_regular_fields(
|
120
|
+
klass, fields, options['fields'], column_strings, join_strings, group_bys, remaining_columns)
|
121
|
+
|
122
|
+
column_strings, join_strings, group_bys, remaining_columns =
|
123
|
+
build_includes(
|
124
|
+
klass, fields, options['include'], column_strings, join_strings, group_bys, remaining_columns)
|
125
|
+
|
126
|
+
column_strings, join_strings, group_bys, use_distinct, remaining_columns =
|
127
|
+
build_concatenations(
|
128
|
+
klass, fields, options['concatenate'], column_strings, join_strings, group_bys, use_distinct, remaining_columns)
|
123
129
|
|
124
130
|
column_strings = add_missing_columns(fields, remaining_columns, column_strings)
|
125
131
|
|
@@ -128,26 +134,37 @@ module Ultrasphinx
|
|
128
134
|
SOURCE_SETTINGS._to_conf_string,
|
129
135
|
setup_source_database(klass),
|
130
136
|
range_select_string(klass),
|
131
|
-
build_query(klass, column_strings, join_strings, condition_strings),
|
137
|
+
build_query(klass, column_strings, join_strings, condition_strings, use_distinct, group_bys),
|
132
138
|
"\n" + groups,
|
133
139
|
query_info_string(klass, class_id),
|
134
140
|
"}\n\n"]
|
135
141
|
end
|
136
142
|
|
137
143
|
|
138
|
-
def build_query(klass, column_strings, join_strings, condition_strings)
|
144
|
+
def build_query(klass, column_strings, join_strings, condition_strings, use_distinct, group_bys)
|
145
|
+
|
146
|
+
primary_key = "#{klass.table_name}.#{klass.primary_key}"
|
147
|
+
group_bys = case ADAPTER
|
148
|
+
when 'mysql'
|
149
|
+
primary_key
|
150
|
+
when 'postgresql'
|
151
|
+
# Postgres is very fussy about GROUP_BY
|
152
|
+
([primary_key] + group_bys.reject {|s| s == primary_key}.uniq.sort).join(', ')
|
153
|
+
end
|
154
|
+
|
139
155
|
["sql_query =",
|
140
|
-
"SELECT",
|
156
|
+
"SELECT",
|
157
|
+
# Avoid DISTINCT; it destroys performance
|
141
158
|
column_strings.sort_by do |string|
|
142
|
-
#
|
159
|
+
# Sphinx wants them always in the same order, but "id" must be first
|
143
160
|
(field = string[/.*AS (.*)/, 1]) == "id" ? "*" : field
|
144
161
|
end.join(", "),
|
145
162
|
"FROM #{klass.table_name}",
|
146
163
|
join_strings.uniq,
|
147
|
-
"WHERE #{
|
164
|
+
"WHERE #{primary_key} >= $start AND #{primary_key} <= $end",
|
148
165
|
condition_strings.uniq.map {|condition| "AND #{condition}" },
|
149
|
-
|
150
|
-
].flatten.join(" ")
|
166
|
+
"GROUP BY #{group_bys}"
|
167
|
+
].flatten.compact.join(" ")
|
151
168
|
end
|
152
169
|
|
153
170
|
|
@@ -159,17 +176,18 @@ module Ultrasphinx
|
|
159
176
|
end
|
160
177
|
|
161
178
|
|
162
|
-
def build_regular_fields(klass, fields, entries, column_strings, join_strings, remaining_columns)
|
179
|
+
def build_regular_fields(klass, fields, entries, column_strings, join_strings, group_bys, remaining_columns)
|
163
180
|
entries.to_a.each do |entry|
|
164
181
|
source_string = "#{entry['table']}.#{entry['field']}"
|
182
|
+
group_bys << source_string
|
165
183
|
column_strings, remaining_columns = install_field(fields, source_string, entry['as'], entry['function_sql'], entry['facet'], column_strings, remaining_columns)
|
166
184
|
end
|
167
185
|
|
168
|
-
[column_strings, join_strings, remaining_columns]
|
186
|
+
[column_strings, join_strings, group_bys, remaining_columns]
|
169
187
|
end
|
170
188
|
|
171
189
|
|
172
|
-
def build_includes(klass, fields, entries, column_strings, join_strings, remaining_columns)
|
190
|
+
def build_includes(klass, fields, entries, column_strings, join_strings, group_bys, remaining_columns)
|
173
191
|
entries.to_a.each do |entry|
|
174
192
|
|
175
193
|
join_klass = entry['class_name'].constantize
|
@@ -189,18 +207,19 @@ module Ultrasphinx
|
|
189
207
|
end
|
190
208
|
|
191
209
|
source_string = "#{entry['table']}.#{entry['field']}"
|
210
|
+
group_bys << source_string
|
192
211
|
column_strings, remaining_columns = install_field(fields, source_string, entry['as'], entry['function_sql'], entry['facet'], column_strings, remaining_columns)
|
193
212
|
end
|
194
213
|
|
195
|
-
[column_strings, join_strings, remaining_columns]
|
214
|
+
[column_strings, join_strings, group_bys, remaining_columns]
|
196
215
|
end
|
197
216
|
|
198
217
|
|
199
|
-
def build_concatenations(klass, fields, entries, column_strings, join_strings, remaining_columns)
|
218
|
+
def build_concatenations(klass, fields, entries, column_strings, join_strings, group_bys, use_distinct, remaining_columns)
|
200
219
|
entries.to_a.each do |entry|
|
201
220
|
if entry['class_name'] and entry['field']
|
202
|
-
#
|
203
|
-
#
|
221
|
+
# Group concats
|
222
|
+
# Only has_many's or explicit sql right now
|
204
223
|
join_klass = entry['class_name'].constantize
|
205
224
|
|
206
225
|
join_strings = install_join_unless_association_sql(entry['association_sql'], nil, join_strings) do
|
@@ -210,13 +229,19 @@ module Ultrasphinx
|
|
210
229
|
(entry['conditions'] ? " AND (#{entry['conditions']})" : "")
|
211
230
|
end
|
212
231
|
|
213
|
-
source_string = "
|
232
|
+
source_string = "#{entry['table']}.#{entry['field']}"
|
233
|
+
# We are using the field in an aggregate, so we don't want to add it to group_bys
|
234
|
+
source_string = ADAPTER_SQL_FUNCTIONS[ADAPTER]['group_concat']._interpolate(source_string)
|
235
|
+
use_distinct = true
|
236
|
+
|
214
237
|
column_strings, remaining_columns = install_field(fields, source_string, entry['as'], entry['function_sql'], entry['facet'], column_strings, remaining_columns)
|
215
238
|
|
216
239
|
elsif entry['fields']
|
217
|
-
#
|
240
|
+
# Regular concats
|
218
241
|
source_string = "CONCAT_WS(' ', " + entry['fields'].map do |subfield|
|
219
242
|
"#{entry['table']}.#{subfield}"
|
243
|
+
end.each do |subsource_string|
|
244
|
+
group_bys << subsource_string
|
220
245
|
end.join(', ') + ")"
|
221
246
|
|
222
247
|
column_strings, remaining_columns = install_field(fields, source_string, entry['as'], entry['function_sql'], entry['facet'], column_strings, remaining_columns)
|
@@ -226,7 +251,7 @@ module Ultrasphinx
|
|
226
251
|
end
|
227
252
|
end
|
228
253
|
|
229
|
-
[column_strings, join_strings, remaining_columns]
|
254
|
+
[column_strings, join_strings, group_bys, use_distinct, remaining_columns]
|
230
255
|
end
|
231
256
|
|
232
257
|
|
@@ -249,7 +274,7 @@ module Ultrasphinx
|
|
249
274
|
|
250
275
|
# Generate hashed integer fields for text grouping
|
251
276
|
if with_facet
|
252
|
-
column_strings << "#{
|
277
|
+
column_strings << "CRC32(#{source_string}) AS #{as}_facet"
|
253
278
|
remaining_columns.delete("#{as}_facet")
|
254
279
|
end
|
255
280
|
[column_strings, remaining_columns]
|
data/lib/ultrasphinx/fields.rb
CHANGED
@@ -60,11 +60,9 @@ This is a special singleton configuration class that stores the index field conf
|
|
60
60
|
|
61
61
|
def cast(source_string, field)
|
62
62
|
if types[field] == "date"
|
63
|
-
"#{
|
63
|
+
"UNIX_TIMESTAMP(#{source_string})"
|
64
64
|
elsif types[field] == "integer"
|
65
65
|
source_string # "CAST(#{source_string} AS UNSIGNED)"
|
66
|
-
elsif source_string =~ /GROUP_CONCAT/
|
67
|
-
"CAST(#{source_string} AS CHAR)"
|
68
66
|
else
|
69
67
|
source_string
|
70
68
|
end + " AS #{field}"
|
@@ -77,7 +75,7 @@ This is a special singleton configuration class that stores the index field conf
|
|
77
75
|
when 'integer', 'float'
|
78
76
|
"0"
|
79
77
|
when 'date'
|
80
|
-
"
|
78
|
+
"18000" # Midnight on 1/1/1970
|
81
79
|
when nil
|
82
80
|
raise "Field #{field} is missing"
|
83
81
|
else
|
@@ -104,17 +102,12 @@ This is a special singleton configuration class that stores the index field conf
|
|
104
102
|
extract_field_alias!(entry, klass)
|
105
103
|
|
106
104
|
unless klass.columns_hash[entry['field']]
|
105
|
+
# XXX I think this is here for migrations
|
107
106
|
Ultrasphinx.say "warning: field #{entry['field']} is not present in #{model}"
|
108
107
|
else
|
109
108
|
save_and_verify_type(entry['as'], klass.columns_hash[entry['field']].type, entry['sortable'], klass)
|
110
|
-
|
111
|
-
|
112
|
-
if entry['facet']
|
113
|
-
save_and_verify_type(entry['as'], 'text', nil, klass) # source must be a string
|
114
|
-
save_and_verify_type("#{entry['as']}_facet", 'integer', nil, klass)
|
115
|
-
end
|
116
|
-
|
117
|
-
entry
|
109
|
+
install_facets!(entry, klass)
|
110
|
+
end
|
118
111
|
end
|
119
112
|
|
120
113
|
# Joins are whatever they are in the target
|
@@ -122,13 +115,15 @@ This is a special singleton configuration class that stores the index field conf
|
|
122
115
|
extract_table_alias!(entry, klass)
|
123
116
|
extract_field_alias!(entry, klass)
|
124
117
|
|
125
|
-
save_and_verify_type(entry['as'] || entry['field'], entry['class_name'].constantize.columns_hash[entry['field']].type, entry['sortable'], klass)
|
118
|
+
save_and_verify_type(entry['as'] || entry['field'], entry['class_name'].constantize.columns_hash[entry['field']].type, entry['sortable'], klass)
|
119
|
+
install_facets!(entry, klass)
|
126
120
|
end
|
127
121
|
|
128
122
|
# Regular concats are CHAR, group_concats are BLOB and need to be cast to CHAR
|
129
123
|
options['concatenate'].to_a.each do |entry|
|
130
124
|
extract_table_alias!(entry, klass) # XXX Doesn't actually do anything useful
|
131
125
|
save_and_verify_type(entry['as'], 'text', entry['sortable'], klass)
|
126
|
+
install_facets!(entry, klass)
|
132
127
|
end
|
133
128
|
|
134
129
|
rescue ActiveRecord::StatementInvalid
|
@@ -139,6 +134,14 @@ This is a special singleton configuration class that stores the index field conf
|
|
139
134
|
self
|
140
135
|
end
|
141
136
|
|
137
|
+
def install_facets!(entry, klass)
|
138
|
+
if entry['facet']
|
139
|
+
save_and_verify_type(entry['as'], 'text', nil, klass) # source must be a string
|
140
|
+
save_and_verify_type("#{entry['as']}_facet", 'integer', nil, klass)
|
141
|
+
end
|
142
|
+
entry
|
143
|
+
end
|
144
|
+
|
142
145
|
def extract_field_alias!(entry, klass)
|
143
146
|
unless entry['as']
|
144
147
|
entry['as'] = entry['field']
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
/* http://osdir.com/ml/db.postgresql.admIN/2003-08/msg00057.html */
|
3
|
+
|
4
|
+
CREATE OR REPLACE FUNCTION MAKE_CONCAT_WS() RETURNS text AS '
|
5
|
+
declare
|
6
|
+
v_args int := 32;
|
7
|
+
v_first text := ''CREATE OR REPLACE FUNCTION CONCAT_WS(text,text,text) RETURNS text AS ''''SELECT CASE WHEN $1 IS NULL THEN NULL WHEN $3 IS NULL THEN $2 ELSE $2 || $1 || $3 END'''' LANGUAGE sql IMMUTABLE'';
|
8
|
+
v_part1 text := ''CREATE OR REPLACE FUNCTION CONCAT_WS(text,text'';
|
9
|
+
v_part2 text := '') RETURNS text AS ''''SELECT CONCAT_WS($1,CONCAT_WS($1,$2'';
|
10
|
+
v_part3 text := '')'''' LANGUAGE sql IMMUTABLE'';
|
11
|
+
v_sql text;
|
12
|
+
|
13
|
+
BEGIN
|
14
|
+
EXECUTE v_first;
|
15
|
+
FOR i IN 4 .. v_args loop
|
16
|
+
v_sql := v_part1;
|
17
|
+
FOR j IN 3 .. i loop
|
18
|
+
v_sql := v_sql || '',text'';
|
19
|
+
END loop;
|
20
|
+
|
21
|
+
v_sql := v_sql || v_part2;
|
22
|
+
|
23
|
+
FOR j IN 3 .. i - 1 loop
|
24
|
+
v_sql := v_sql || '',$'' || j::text;
|
25
|
+
END loop;
|
26
|
+
v_sql := v_sql || ''),$'' || i::text;
|
27
|
+
|
28
|
+
v_sql := v_sql || v_part3;
|
29
|
+
EXECUTE v_sql;
|
30
|
+
END loop;
|
31
|
+
RETURN ''OK'';
|
32
|
+
END;
|
33
|
+
' LANGUAGE 'plpgsql';
|
34
|
+
|
35
|
+
SELECT MAKE_CONCAT_WS();
|