ultrasphinx 1.5.2 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data.tar.gz.sig +2 -3
  2. data/CHANGELOG +2 -0
  3. data/Manifest +134 -28
  4. data/TODO +0 -1
  5. data/examples/{app.multi → ap.multi} +1 -1
  6. data/examples/default.base +2 -0
  7. data/lib/ultrasphinx.rb +19 -17
  8. data/lib/ultrasphinx/configure.rb +36 -28
  9. data/lib/ultrasphinx/core_extensions.rb +11 -1
  10. data/lib/ultrasphinx/fields.rb +16 -9
  11. data/lib/ultrasphinx/hex_to_int.sql +15 -0
  12. data/lib/ultrasphinx/is_indexed.rb +9 -7
  13. data/lib/ultrasphinx/search.rb +27 -13
  14. data/lib/ultrasphinx/search/internals.rb +36 -16
  15. data/lib/ultrasphinx/spell.rb +13 -4
  16. data/lib/ultrasphinx/ultrasphinx.rb +30 -20
  17. data/tasks/ultrasphinx.rake +31 -6
  18. data/test/integration/app/README +182 -0
  19. data/test/integration/app/Rakefile +10 -0
  20. data/test/integration/app/app/controllers/addresses_controller.rb +85 -0
  21. data/test/integration/app/app/controllers/application.rb +7 -0
  22. data/test/integration/app/app/controllers/sellers_controller.rb +85 -0
  23. data/test/integration/app/app/controllers/states_controller.rb +85 -0
  24. data/test/integration/app/app/controllers/users_controller.rb +85 -0
  25. data/test/integration/app/app/helpers/addresses_helper.rb +2 -0
  26. data/test/integration/app/app/helpers/application_helper.rb +3 -0
  27. data/test/integration/app/app/helpers/sellers_helper.rb +28 -0
  28. data/test/integration/app/app/helpers/states_helper.rb +2 -0
  29. data/test/integration/app/app/helpers/users_helper.rb +2 -0
  30. data/test/integration/app/app/models/geo/address.rb +8 -0
  31. data/test/integration/app/app/models/geo/state.rb +5 -0
  32. data/test/integration/app/app/models/person/user.rb +9 -0
  33. data/test/integration/app/app/models/seller.rb +20 -0
  34. data/test/integration/app/app/views/addresses/edit.html.erb +12 -0
  35. data/test/integration/app/app/views/addresses/index.html.erb +18 -0
  36. data/test/integration/app/app/views/addresses/new.html.erb +11 -0
  37. data/test/integration/app/app/views/addresses/show.html.erb +3 -0
  38. data/test/integration/app/app/views/layouts/addresses.html.erb +17 -0
  39. data/test/integration/app/app/views/layouts/sellers.html.erb +17 -0
  40. data/test/integration/app/app/views/layouts/states.html.erb +17 -0
  41. data/test/integration/app/app/views/layouts/users.html.erb +17 -0
  42. data/test/integration/app/app/views/sellers/edit.html.erb +12 -0
  43. data/test/integration/app/app/views/sellers/index.html.erb +20 -0
  44. data/test/integration/app/app/views/sellers/new.html.erb +11 -0
  45. data/test/integration/app/app/views/sellers/show.html.erb +3 -0
  46. data/test/integration/app/app/views/states/edit.html.erb +12 -0
  47. data/test/integration/app/app/views/states/index.html.erb +19 -0
  48. data/test/integration/app/app/views/states/new.html.erb +11 -0
  49. data/test/integration/app/app/views/states/show.html.erb +3 -0
  50. data/test/integration/app/app/views/users/edit.html.erb +12 -0
  51. data/test/integration/app/app/views/users/index.html.erb +22 -0
  52. data/test/integration/app/app/views/users/new.html.erb +11 -0
  53. data/test/integration/app/app/views/users/show.html.erb +3 -0
  54. data/test/integration/app/config/boot.rb +45 -0
  55. data/test/integration/app/config/database.yml +21 -0
  56. data/test/integration/app/config/environment.rb +11 -0
  57. data/test/integration/app/config/environments/development.rb +7 -0
  58. data/test/integration/app/config/environments/production.rb +18 -0
  59. data/test/integration/app/config/environments/test.rb +19 -0
  60. data/test/integration/app/config/locomotive.yml +6 -0
  61. data/test/integration/app/config/routes.rb +33 -0
  62. data/test/integration/app/config/ultrasphinx/default.base +56 -0
  63. data/test/integration/app/config/ultrasphinx/development.conf +159 -0
  64. data/test/integration/app/config/ultrasphinx/development.conf.canonical +159 -0
  65. data/test/integration/app/db/migrate/001_create_users.rb +16 -0
  66. data/test/integration/app/db/migrate/002_create_sellers.rb +14 -0
  67. data/test/integration/app/db/migrate/003_create_addresses.rb +19 -0
  68. data/test/integration/app/db/migrate/004_create_states.rb +12 -0
  69. data/test/integration/app/db/migrate/005_add_capitalization_to_seller.rb +9 -0
  70. data/test/integration/app/db/migrate/006_add_deleted_to_user.rb +9 -0
  71. data/test/integration/app/db/migrate/007_add_lat_and_long_to_address.rb +11 -0
  72. data/test/integration/app/db/migrate/008_add_mission_statement_to_seller.rb +9 -0
  73. data/test/integration/app/db/schema.rb +45 -0
  74. data/test/integration/app/doc/README_FOR_APP +2 -0
  75. data/test/integration/app/public/404.html +30 -0
  76. data/test/integration/app/public/500.html +30 -0
  77. data/test/integration/app/public/dispatch.cgi +10 -0
  78. data/test/integration/app/public/dispatch.fcgi +24 -0
  79. data/test/integration/app/public/dispatch.rb +10 -0
  80. data/test/integration/app/public/favicon.ico +0 -0
  81. data/test/integration/app/public/images/rails.png +0 -0
  82. data/test/integration/app/public/index.html +277 -0
  83. data/test/integration/app/public/javascripts/application.js +2 -0
  84. data/test/integration/app/public/javascripts/controls.js +833 -0
  85. data/test/integration/app/public/javascripts/dragdrop.js +942 -0
  86. data/test/integration/app/public/javascripts/effects.js +1088 -0
  87. data/test/integration/app/public/javascripts/prototype.js +2515 -0
  88. data/test/integration/app/public/robots.txt +1 -0
  89. data/test/integration/app/public/stylesheets/scaffold.css +74 -0
  90. data/test/integration/app/script/about +3 -0
  91. data/test/integration/app/script/breakpointer +3 -0
  92. data/test/integration/app/script/console +3 -0
  93. data/test/integration/app/script/destroy +3 -0
  94. data/test/integration/app/script/generate +3 -0
  95. data/test/integration/app/script/performance/benchmarker +3 -0
  96. data/test/integration/app/script/performance/profiler +3 -0
  97. data/test/integration/app/script/plugin +3 -0
  98. data/test/integration/app/script/process/inspector +3 -0
  99. data/test/integration/app/script/process/reaper +3 -0
  100. data/test/integration/app/script/process/spawner +3 -0
  101. data/test/integration/app/script/runner +3 -0
  102. data/test/integration/app/script/server +3 -0
  103. data/test/integration/app/test/fixtures/addresses.yml +13 -0
  104. data/test/integration/app/test/fixtures/sellers.yml +11 -0
  105. data/test/integration/app/test/fixtures/states.yml +216 -0
  106. data/test/integration/app/test/fixtures/users.yml +11 -0
  107. data/test/integration/app/test/functional/addresses_controller_test.rb +57 -0
  108. data/test/integration/app/test/functional/sellers_controller_test.rb +57 -0
  109. data/test/integration/app/test/functional/states_controller_test.rb +57 -0
  110. data/test/integration/app/test/functional/users_controller_test.rb +57 -0
  111. data/test/integration/app/test/test_helper.rb +28 -0
  112. data/test/integration/app/test/unit/address_test.rb +10 -0
  113. data/test/integration/app/test/unit/seller_test.rb +10 -0
  114. data/test/integration/app/test/unit/state_test.rb +10 -0
  115. data/test/integration/app/test/unit/user_test.rb +10 -0
  116. data/test/integration/configure_test.rb +23 -0
  117. data/test/integration/search_test.rb +221 -0
  118. data/test/integration/server_test.rb +38 -0
  119. data/test/integration/spell_test.rb +15 -0
  120. data/test/setup.rb +12 -0
  121. data/test/test_all.rb +1 -0
  122. data/test/test_helper.rb +13 -24
  123. data/test/ts.multi +2 -0
  124. data/test/unit/parser_test.rb +86 -86
  125. data/ultrasphinx.gemspec +12 -5
  126. metadata +136 -30
  127. metadata.gz.sig +0 -0
data.tar.gz.sig CHANGED
@@ -1,3 +1,2 @@
1
- �v� #w��u����gxO���+sI)^�~�7ذ}P��]��c$���Rb�nb
2
- O���G��*������IG���
3
- T��8�?λ�p� ����PG&�9�b@
1
+ ��MÒ;�`鱤"��D8f���H^&�U(�
2
+ ޣ���Œ8�P�qkz=������+i�l�g ��k�gZ��i��,���ޱ�����\Vl�Q��h�Q�����v�^~�3�W;�ef���lݟ��ؐ���K|�P���h�+vU�Ι턎W�p� �1��U,�G���j�vo[� I!��u�5(.I3.f��Bo� ]��T.l`�Х���u-�^�����&��B�ǭ��;b[8�9�c��PE�Y��G��O0\k�
data/CHANGELOG CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ v1.5.3. 90% test coverage; support multiple spelling dictionaries per machine (configurable in the .base file); association_name key is right out; some bugfixes.
3
+
2
4
  v1.5.2. Fix association reloading issue; support float attributes on Sphinx 0.9.8; fix date range filters; import and update sample app (Mark Lane); start a comprehensive integration suite.
3
5
 
4
6
  v1.5.1. Various bugfixes.
data/Manifest CHANGED
@@ -1,29 +1,135 @@
1
- vendor/will_paginate/LICENSE
2
- vendor/sphinx/README
3
- vendor/sphinx/Rakefile
4
- vendor/sphinx/LICENSE
5
- vendor/sphinx/lib/client.rb
6
- vendor/sphinx/init.rb
7
- TODO
8
- test/unit/parser_test.rb
9
- test/test_helper.rb
10
- test/config/ultrasphinx/test.base
11
- tasks/ultrasphinx.rake
12
- README
13
- Manifest
14
- LICENSE
15
- lib/ultrasphinx.rb
16
- lib/ultrasphinx/ultrasphinx.rb
17
- lib/ultrasphinx/spell.rb
18
- lib/ultrasphinx/search.rb
19
- lib/ultrasphinx/search/parser.rb
20
- lib/ultrasphinx/search/internals.rb
21
- lib/ultrasphinx/is_indexed.rb
22
- lib/ultrasphinx/fields.rb
23
- lib/ultrasphinx/core_extensions.rb
24
- lib/ultrasphinx/configure.rb
25
- lib/ultrasphinx/autoload.rb
26
- init.rb
27
- examples/default.base
28
- examples/app.multi
29
1
  CHANGELOG
2
+ examples/ap.multi
3
+ examples/default.base
4
+ init.rb
5
+ lib/ultrasphinx/autoload.rb
6
+ lib/ultrasphinx/configure.rb
7
+ lib/ultrasphinx/core_extensions.rb
8
+ lib/ultrasphinx/fields.rb
9
+ lib/ultrasphinx/hex_to_int.sql
10
+ lib/ultrasphinx/is_indexed.rb
11
+ lib/ultrasphinx/search/internals.rb
12
+ lib/ultrasphinx/search/parser.rb
13
+ lib/ultrasphinx/search.rb
14
+ lib/ultrasphinx/spell.rb
15
+ lib/ultrasphinx/ultrasphinx.rb
16
+ lib/ultrasphinx.rb
17
+ LICENSE
18
+ Manifest
19
+ README
20
+ tasks/ultrasphinx.rake
21
+ test/config/ultrasphinx/test.base
22
+ test/integration/app/app/controllers/addresses_controller.rb
23
+ test/integration/app/app/controllers/application.rb
24
+ test/integration/app/app/controllers/sellers_controller.rb
25
+ test/integration/app/app/controllers/states_controller.rb
26
+ test/integration/app/app/controllers/users_controller.rb
27
+ test/integration/app/app/helpers/addresses_helper.rb
28
+ test/integration/app/app/helpers/application_helper.rb
29
+ test/integration/app/app/helpers/sellers_helper.rb
30
+ test/integration/app/app/helpers/states_helper.rb
31
+ test/integration/app/app/helpers/users_helper.rb
32
+ test/integration/app/app/models/geo/address.rb
33
+ test/integration/app/app/models/geo/state.rb
34
+ test/integration/app/app/models/person/user.rb
35
+ test/integration/app/app/models/seller.rb
36
+ test/integration/app/app/views/addresses/edit.html.erb
37
+ test/integration/app/app/views/addresses/index.html.erb
38
+ test/integration/app/app/views/addresses/new.html.erb
39
+ test/integration/app/app/views/addresses/show.html.erb
40
+ test/integration/app/app/views/layouts/addresses.html.erb
41
+ test/integration/app/app/views/layouts/sellers.html.erb
42
+ test/integration/app/app/views/layouts/states.html.erb
43
+ test/integration/app/app/views/layouts/users.html.erb
44
+ test/integration/app/app/views/sellers/edit.html.erb
45
+ test/integration/app/app/views/sellers/index.html.erb
46
+ test/integration/app/app/views/sellers/new.html.erb
47
+ test/integration/app/app/views/sellers/show.html.erb
48
+ test/integration/app/app/views/states/edit.html.erb
49
+ test/integration/app/app/views/states/index.html.erb
50
+ test/integration/app/app/views/states/new.html.erb
51
+ test/integration/app/app/views/states/show.html.erb
52
+ test/integration/app/app/views/users/edit.html.erb
53
+ test/integration/app/app/views/users/index.html.erb
54
+ test/integration/app/app/views/users/new.html.erb
55
+ test/integration/app/app/views/users/show.html.erb
56
+ test/integration/app/config/boot.rb
57
+ test/integration/app/config/database.yml
58
+ test/integration/app/config/environment.rb
59
+ test/integration/app/config/environments/development.rb
60
+ test/integration/app/config/environments/production.rb
61
+ test/integration/app/config/environments/test.rb
62
+ test/integration/app/config/locomotive.yml
63
+ test/integration/app/config/routes.rb
64
+ test/integration/app/config/ultrasphinx/default.base
65
+ test/integration/app/config/ultrasphinx/development.conf
66
+ test/integration/app/config/ultrasphinx/development.conf.canonical
67
+ test/integration/app/db/migrate/001_create_users.rb
68
+ test/integration/app/db/migrate/002_create_sellers.rb
69
+ test/integration/app/db/migrate/003_create_addresses.rb
70
+ test/integration/app/db/migrate/004_create_states.rb
71
+ test/integration/app/db/migrate/005_add_capitalization_to_seller.rb
72
+ test/integration/app/db/migrate/006_add_deleted_to_user.rb
73
+ test/integration/app/db/migrate/007_add_lat_and_long_to_address.rb
74
+ test/integration/app/db/migrate/008_add_mission_statement_to_seller.rb
75
+ test/integration/app/db/schema.rb
76
+ test/integration/app/doc/README_FOR_APP
77
+ test/integration/app/public/404.html
78
+ test/integration/app/public/500.html
79
+ test/integration/app/public/dispatch.cgi
80
+ test/integration/app/public/dispatch.fcgi
81
+ test/integration/app/public/dispatch.rb
82
+ test/integration/app/public/favicon.ico
83
+ test/integration/app/public/images/rails.png
84
+ test/integration/app/public/index.html
85
+ test/integration/app/public/javascripts/application.js
86
+ test/integration/app/public/javascripts/controls.js
87
+ test/integration/app/public/javascripts/dragdrop.js
88
+ test/integration/app/public/javascripts/effects.js
89
+ test/integration/app/public/javascripts/prototype.js
90
+ test/integration/app/public/robots.txt
91
+ test/integration/app/public/stylesheets/scaffold.css
92
+ test/integration/app/Rakefile
93
+ test/integration/app/README
94
+ test/integration/app/script/about
95
+ test/integration/app/script/breakpointer
96
+ test/integration/app/script/console
97
+ test/integration/app/script/destroy
98
+ test/integration/app/script/generate
99
+ test/integration/app/script/performance/benchmarker
100
+ test/integration/app/script/performance/profiler
101
+ test/integration/app/script/plugin
102
+ test/integration/app/script/process/inspector
103
+ test/integration/app/script/process/reaper
104
+ test/integration/app/script/process/spawner
105
+ test/integration/app/script/runner
106
+ test/integration/app/script/server
107
+ test/integration/app/test/fixtures/addresses.yml
108
+ test/integration/app/test/fixtures/sellers.yml
109
+ test/integration/app/test/fixtures/states.yml
110
+ test/integration/app/test/fixtures/users.yml
111
+ test/integration/app/test/functional/addresses_controller_test.rb
112
+ test/integration/app/test/functional/sellers_controller_test.rb
113
+ test/integration/app/test/functional/states_controller_test.rb
114
+ test/integration/app/test/functional/users_controller_test.rb
115
+ test/integration/app/test/test_helper.rb
116
+ test/integration/app/test/unit/address_test.rb
117
+ test/integration/app/test/unit/seller_test.rb
118
+ test/integration/app/test/unit/state_test.rb
119
+ test/integration/app/test/unit/user_test.rb
120
+ test/integration/configure_test.rb
121
+ test/integration/search_test.rb
122
+ test/integration/server_test.rb
123
+ test/integration/spell_test.rb
124
+ test/setup.rb
125
+ test/test_all.rb
126
+ test/test_helper.rb
127
+ test/ts.multi
128
+ test/unit/parser_test.rb
129
+ TODO
130
+ vendor/sphinx/init.rb
131
+ vendor/sphinx/lib/client.rb
132
+ vendor/sphinx/LICENSE
133
+ vendor/sphinx/Rakefile
134
+ vendor/sphinx/README
135
+ vendor/will_paginate/LICENSE
data/TODO CHANGED
@@ -1,5 +1,4 @@
1
1
 
2
- * Support multiple spelling dictionaries per machine
3
2
  * Finish unifying filters and textfields
4
3
  * Support exclude filters
5
4
  * Make sure filters can be set to nil
@@ -1,2 +1,2 @@
1
1
  add en_US-w_accents.multi
2
- add custom.rws
2
+ add ap.rws
@@ -29,6 +29,8 @@ searchd
29
29
  client
30
30
  {
31
31
  # Client options
32
+ # Name of the Aspell dictionary (two letters max)
33
+ dictionary_name = ap
32
34
  # How your application connects to the search daemon (not necessarily the same as above)
33
35
  server_host = localhost
34
36
  server_port = 3312
@@ -3,31 +3,33 @@ require 'fileutils'
3
3
  require 'chronic'
4
4
  require 'singleton'
5
5
 
6
+ if defined? RAILS_ENV and RAILS_ENV == "development"
7
+ if ENV['USER'] == 'eweaver'
8
+ require 'ruby-debug'
9
+ Debugger.start
10
+ end
11
+ end
12
+
6
13
  require "#{File.dirname(__FILE__)}/../vendor/sphinx/lib/client"
7
14
 
8
15
  require 'ultrasphinx/ultrasphinx'
9
16
  require 'ultrasphinx/core_extensions'
10
- require 'ultrasphinx/configure'
11
- require 'ultrasphinx/autoload'
12
- require 'ultrasphinx/fields'
13
17
  require 'ultrasphinx/is_indexed'
14
- require 'ultrasphinx/search/internals'
15
- require 'ultrasphinx/search/parser'
16
- require 'ultrasphinx/search'
17
18
 
18
- Ultrasphinx.say(
19
+ if (ActiveRecord::Base.connection rescue nil)
20
+ require 'ultrasphinx/configure'
21
+ require 'ultrasphinx/autoload'
22
+ require 'ultrasphinx/fields'
23
+
24
+ require 'ultrasphinx/search/internals'
25
+ require 'ultrasphinx/search/parser'
26
+ require 'ultrasphinx/search'
27
+
19
28
  begin
20
29
  require 'raspell'
21
- require 'ultrasphinx/spell'
22
- "spelling support enabled"
23
30
  rescue Object => e
24
- "spelling support not available (module load raised \"#{e}\")"
25
31
  end
26
- )
32
+
33
+ require 'ultrasphinx/spell'
34
+ end
27
35
 
28
- if defined? RAILS_ENV and RAILS_ENV == "development"
29
- if ENV['USER'] == 'eweaver'
30
- require 'ruby-debug'
31
- Debugger.start
32
- end
33
- end
@@ -3,21 +3,28 @@ module Ultrasphinx
3
3
  class Configure
4
4
  class << self
5
5
 
6
- # Force all the indexed models to load and fill the MODEL_CONFIGURATION hash.
6
+ # Force all the indexed models to load and register in the MODEL_CONFIGURATION hash.
7
7
  def load_constants
8
8
 
9
- Dir["#{RAILS_ROOT}/app/models/**/*.rb"].each do |filename|
10
- next if filename =~ /\/(\.svn|CVS|\.bzr)\//
11
- open(filename) do |file|
12
- begin
13
- if file.grep(/is_indexed/).any?
14
- Dependencies.load_missing_constant(Kernel, File.basename(filename)[0..-4].classify)
9
+ Dir.chdir "#{RAILS_ROOT}/app/models/" do
10
+ Dir["**/*.rb"].each do |filename|
11
+ open(filename) do |file|
12
+ begin
13
+ if file.grep(/is_indexed/).any?
14
+ filename = filename[0..-4]
15
+ begin
16
+ File.basename(filename).camelize.constantize
17
+ rescue NameError => e
18
+ filename.camelize.constantize
19
+ end
20
+ end
21
+ rescue Object => e
22
+ say "warning: possibly critical autoload error on #{filename}"
23
+ say e.inspect
24
+ #say e.backtrace.join("\n") if RAILS_ENV == "development"
15
25
  end
16
- rescue Object => e
17
- say "warning: possibly critical autoload error on #{filename}"
18
- say e.inspect
19
- end
20
- end
26
+ end
27
+ end
21
28
  end
22
29
 
23
30
  # Build the field-to-type mappings.
@@ -41,7 +48,7 @@ module Ultrasphinx
41
48
  cached_groups = Fields.instance.groups.join("\n")
42
49
  MODEL_CONFIGURATION.each_with_index do |model_options, class_id|
43
50
  model, options = model_options
44
- klass, source = model.constantize, model.tableize
51
+ klass, source = model.constantize, model.tableize.gsub('/', '__')
45
52
  sources << source
46
53
  conf.puts build_source(Fields.instance, model, options, class_id, klass, source, cached_groups)
47
54
  end
@@ -58,7 +65,7 @@ module Ultrasphinx
58
65
  def global_header
59
66
  ["\n# Auto-generated at #{Time.now}.",
60
67
  "# Hand modifications will be overwritten.",
61
- "# #{BASE_PATH}",
68
+ "# #{BASE_PATH}\n",
62
69
  INDEXER_SETTINGS._to_conf_string('indexer'),
63
70
  DAEMON_SETTINGS._to_conf_string("searchd")]
64
71
  end
@@ -130,7 +137,6 @@ module Ultrasphinx
130
137
 
131
138
 
132
139
  def build_query(klass, column_strings, join_strings, condition_strings)
133
-
134
140
  ["sql_query =",
135
141
  "SELECT",
136
142
  column_strings.sort_by do |string|
@@ -140,9 +146,7 @@ module Ultrasphinx
140
146
  "FROM #{klass.table_name}",
141
147
  join_strings.uniq,
142
148
  "WHERE #{klass.table_name}.#{klass.primary_key} >= $start AND #{klass.table_name}.#{klass.primary_key} <= $end",
143
- condition_strings.uniq.map do |condition|
144
- "AND #{condition}"
145
- end,
149
+ condition_strings.uniq.map {|condition| "AND #{condition}" },
146
150
  ADAPTER_SQL_FUNCTIONS[ADAPTER]['group_by']
147
151
  ].flatten.join(" ")
148
152
  end
@@ -168,9 +172,9 @@ module Ultrasphinx
168
172
 
169
173
  def build_includes(klass, fields, entries, column_strings, join_strings, remaining_columns)
170
174
  entries.to_a.each do |entry|
171
-
175
+
172
176
  join_klass = entry['class_name'].constantize
173
- association = klass.reflect_on_association(entry['class_name'].underscore.to_sym)
177
+ association = association_by_class_name(klass, entry['class_name'])
174
178
 
175
179
  raise ConfigurationError, "Unknown association from #{klass} to #{entry['class_name']}" if not association and not entry['association_sql']
176
180
 
@@ -179,9 +183,9 @@ module Ultrasphinx
179
183
  if (macro = association.macro) == :belongs_to
180
184
  "#{join_klass.table_name}.#{join_klass.primary_key} = #{klass.table_name}.#{association.primary_key_name}"
181
185
  elsif macro == :has_one
182
- "#{klass.table_name}.#{klass.primary_key} = #{join_klass.table_name}.#{association.instance_variable_get('@foreign_key_name')}"
186
+ "#{klass.table_name}.#{klass.primary_key} = #{join_klass.table_name}.#{association.primary_key_name}"
183
187
  else
184
- raise ConfigurationError, "Unidentified association macro #{macro.inspect}"
188
+ raise ConfigurationError, "Unidentified association macro #{macro.inspect}. Please use the :association_sql key to manually specify the JOIN syntax."
185
189
  end
186
190
  end
187
191
 
@@ -202,7 +206,7 @@ module Ultrasphinx
202
206
 
203
207
  join_strings = install_join_unless_association_sql(entry['association_sql'], nil, join_strings) do
204
208
  # XXX make sure foreign key is right for polymorphic relationships
205
- association = klass.reflect_on_association(entry['association_name'] ? entry['association_name'].to_sym : entry['class_name'].underscore.pluralize.to_sym)
209
+ association = association_by_class_name(klass, entry['class_name'])
206
210
  "LEFT OUTER JOIN #{join_klass.table_name} ON #{klass.table_name}.#{klass.primary_key} = #{join_klass.table_name}.#{association.primary_key_name}" +
207
211
  (entry['conditions'] ? " AND (#{entry['conditions']})" : "")
208
212
  end
@@ -239,15 +243,14 @@ module Ultrasphinx
239
243
 
240
244
 
241
245
  def install_field(fields, source_string, as, function_sql, with_facet, column_strings, remaining_columns)
242
- source_string = function_sql.sub('?', source_string) if function_sql
246
+ source_string = function_sql._interpolate(source_string) if function_sql
243
247
 
244
248
  column_strings << fields.cast(source_string, as)
245
249
  remaining_columns.delete(as)
246
250
 
247
- # Generate CRC integer fields for text grouping
251
+ # Generate hashed integer fields for text grouping
248
252
  if with_facet
249
- # Postgres probably doesn't handle this
250
- column_strings << "CRC32(#{source_string}) AS #{as}_facet"
253
+ column_strings << "#{ADAPTER_SQL_FUNCTIONS[ADAPTER]['hash']._interpolate(source_string)} AS #{as}_facet"
251
254
  remaining_columns.delete("#{as}_facet")
252
255
  end
253
256
  [column_strings, remaining_columns]
@@ -257,7 +260,12 @@ module Ultrasphinx
257
260
  def install_join_unless_association_sql(association_sql, join_string, join_strings)
258
261
  join_strings << (association_sql or join_string or yield)
259
262
  end
260
-
263
+
264
+ def association_by_class_name(klass, class_name)
265
+ klass.reflect_on_all_associations.detect do |assoc|
266
+ assoc.class_name == class_name
267
+ end
268
+ end
261
269
 
262
270
  def say(s)
263
271
  Ultrasphinx.say s
@@ -6,6 +6,12 @@ class Array
6
6
  set + Array(element)
7
7
  end
8
8
  end
9
+
10
+ def _sum
11
+ self.inject(0) do |acc, element|
12
+ acc + element
13
+ end
14
+ end
9
15
  end
10
16
 
11
17
  class Object
@@ -66,9 +72,13 @@ class String
66
72
  elsif date = Chronic.parse(self)
67
73
  date.to_i
68
74
  else
69
- self
75
+ raise Ultrasphinx::UsageError, "#{self.inspect} could not be coerced into a numeric value"
70
76
  end
71
77
  end
78
+
79
+ def _interpolate(value)
80
+ self.sub('?', value)
81
+ end
72
82
  end
73
83
 
74
84
  module Ultrasphinx::NumericSelf
@@ -11,11 +11,12 @@ This is a special singleton configuration class that stores the index field conf
11
11
  TYPE_MAP = {
12
12
  'string' => 'text',
13
13
  'text' => 'text',
14
- 'integer' => 'numeric',
14
+ 'integer' => 'integer',
15
15
  'date' => 'date',
16
16
  'datetime' => 'date',
17
17
  'timestamp' => 'date',
18
- 'float' => 'numeric'
18
+ 'float' => 'float',
19
+ 'boolean' => 'integer'
19
20
  }
20
21
 
21
22
  VERSIONS_REQUIRED = {'float' => '0.9.8'}
@@ -50,7 +51,7 @@ This is a special singleton configuration class that stores the index field conf
50
51
  classes[field] = [klass]
51
52
 
52
53
  @groups << case new_type
53
- when 'numeric'
54
+ when 'float', 'integer'
54
55
  "sql_group_column = #{field}"
55
56
  when 'date'
56
57
  "sql_date_column = #{field}"
@@ -62,7 +63,9 @@ This is a special singleton configuration class that stores the index field conf
62
63
 
63
64
  def cast(source_string, field)
64
65
  if types[field] == "date"
65
- "#{ADAPTER_SQL_FUNCTIONS[ADAPTER]['timestamp']}#{source_string})"
66
+ "#{ADAPTER_SQL_FUNCTIONS[ADAPTER]['timestamp']._interpolate(source_string)}"
67
+ elsif types[field] == "integer"
68
+ source_string # "CAST(#{source_string} AS UNSIGNED)"
66
69
  elsif source_string =~ /GROUP_CONCAT/
67
70
  "CAST(#{source_string} AS CHAR)"
68
71
  else
@@ -74,12 +77,14 @@ This is a special singleton configuration class that stores the index field conf
74
77
  case types[field]
75
78
  when 'text'
76
79
  "''"
77
- when 'numeric'
80
+ when 'integer', 'float'
78
81
  "0"
79
82
  when 'date'
80
83
  "UNIX_TIMESTAMP('1970-01-01 00:00:00')"
84
+ when nil
85
+ raise "Field #{field} is missing"
81
86
  else
82
- raise "Field #{field} does not have a valid type."
87
+ raise "Field #{field} does not have a valid type #{types[field]}."
83
88
  end + " AS #{field}"
84
89
  end
85
90
 
@@ -103,9 +108,9 @@ This is a special singleton configuration class that stores the index field conf
103
108
 
104
109
  begin
105
110
 
106
- # Fields are from the model. We destructively canonicize them back onto the configuration hash.
111
+ # Fields are from the model
112
+ # We destructively canonicize them back onto the configuration hash
107
113
  options['fields'] = options['fields'].to_a.map do |entry|
108
-
109
114
  entry = {'field' => entry} unless entry.is_a? Hash
110
115
  entry['as'] = entry['field'] unless entry['as']
111
116
 
@@ -125,10 +130,12 @@ This is a special singleton configuration class that stores the index field conf
125
130
 
126
131
  # Joins are whatever they are in the target
127
132
  options['include'].to_a.each do |entry|
133
+ entry['as'] = entry['field'] unless entry['as']
134
+
128
135
  save_and_verify_type(entry['as'] || entry['field'], entry['class_name'].constantize.columns_hash[entry['field']].type, entry['sortable'], klass)
129
136
  end
130
137
 
131
- # Regular concats are CHAR (I think), group_concats are BLOB and need to be cast to CHAR, e.g. :text
138
+ # Regular concats are CHAR, group_concats are BLOB and need to be cast to CHAR
132
139
  options['concatenate'].to_a.each do |entry|
133
140
  save_and_verify_type(entry['as'], 'text', entry['sortable'], klass)
134
141
  end