ultrasphinx 1.5.2 → 1.5.3

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.
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