acts_as_solr 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. data/.gitignore +8 -0
  2. data/CHANGE_LOG +233 -0
  3. data/FORKED_CHANGES +3 -0
  4. data/LICENSE +19 -0
  5. data/README.markdown +94 -0
  6. data/README.rdoc +84 -0
  7. data/Rakefile +57 -0
  8. data/TESTING_THE_PLUGIN +25 -0
  9. data/VERSION +1 -0
  10. data/acts_as_solr.gemspec +237 -0
  11. data/config/solr.yml +15 -0
  12. data/config/solr_environment.rb +22 -0
  13. data/init.rb +21 -0
  14. data/install.rb +11 -0
  15. data/lib/acts_as_solr.rb +61 -0
  16. data/lib/acts_methods.rb +284 -0
  17. data/lib/class_methods.rb +239 -0
  18. data/lib/common_methods.rb +89 -0
  19. data/lib/deprecation.rb +61 -0
  20. data/lib/instance_methods.rb +181 -0
  21. data/lib/lazy_document.rb +18 -0
  22. data/lib/parser_methods.rb +230 -0
  23. data/lib/search_results.rb +69 -0
  24. data/lib/solr/connection.rb +191 -0
  25. data/lib/solr/document.rb +78 -0
  26. data/lib/solr/exception.rb +13 -0
  27. data/lib/solr/field.rb +39 -0
  28. data/lib/solr/importer/array_mapper.rb +26 -0
  29. data/lib/solr/importer/delimited_file_source.rb +38 -0
  30. data/lib/solr/importer/hpricot_mapper.rb +27 -0
  31. data/lib/solr/importer/mapper.rb +51 -0
  32. data/lib/solr/importer/solr_source.rb +43 -0
  33. data/lib/solr/importer/xpath_mapper.rb +35 -0
  34. data/lib/solr/importer.rb +19 -0
  35. data/lib/solr/indexer.rb +52 -0
  36. data/lib/solr/request/add_document.rb +63 -0
  37. data/lib/solr/request/base.rb +36 -0
  38. data/lib/solr/request/commit.rb +31 -0
  39. data/lib/solr/request/delete.rb +50 -0
  40. data/lib/solr/request/dismax.rb +46 -0
  41. data/lib/solr/request/index_info.rb +22 -0
  42. data/lib/solr/request/modify_document.rb +51 -0
  43. data/lib/solr/request/optimize.rb +21 -0
  44. data/lib/solr/request/ping.rb +36 -0
  45. data/lib/solr/request/select.rb +56 -0
  46. data/lib/solr/request/spellcheck.rb +30 -0
  47. data/lib/solr/request/standard.rb +402 -0
  48. data/lib/solr/request/update.rb +23 -0
  49. data/lib/solr/request.rb +26 -0
  50. data/lib/solr/response/add_document.rb +17 -0
  51. data/lib/solr/response/base.rb +42 -0
  52. data/lib/solr/response/commit.rb +17 -0
  53. data/lib/solr/response/delete.rb +13 -0
  54. data/lib/solr/response/dismax.rb +8 -0
  55. data/lib/solr/response/index_info.rb +26 -0
  56. data/lib/solr/response/modify_document.rb +17 -0
  57. data/lib/solr/response/optimize.rb +14 -0
  58. data/lib/solr/response/ping.rb +28 -0
  59. data/lib/solr/response/ruby.rb +42 -0
  60. data/lib/solr/response/select.rb +17 -0
  61. data/lib/solr/response/spellcheck.rb +20 -0
  62. data/lib/solr/response/standard.rb +64 -0
  63. data/lib/solr/response/xml.rb +42 -0
  64. data/lib/solr/response.rb +27 -0
  65. data/lib/solr/solrtasks.rb +27 -0
  66. data/lib/solr/util.rb +32 -0
  67. data/lib/solr/xml.rb +44 -0
  68. data/lib/solr.rb +21 -0
  69. data/lib/solr_fixtures.rb +13 -0
  70. data/lib/tasks/database.rake +18 -0
  71. data/lib/tasks/solr.rake +137 -0
  72. data/lib/tasks/test.rake +7 -0
  73. data/lib/will_paginate_support.rb +12 -0
  74. data/solr/CHANGES.txt +1207 -0
  75. data/solr/LICENSE.txt +712 -0
  76. data/solr/NOTICE.txt +90 -0
  77. data/solr/etc/jetty.xml +205 -0
  78. data/solr/etc/webdefault.xml +379 -0
  79. data/solr/lib/easymock.jar +0 -0
  80. data/solr/lib/jetty-6.1.3.jar +0 -0
  81. data/solr/lib/jetty-util-6.1.3.jar +0 -0
  82. data/solr/lib/jsp-2.1/ant-1.6.5.jar +0 -0
  83. data/solr/lib/jsp-2.1/core-3.1.1.jar +0 -0
  84. data/solr/lib/jsp-2.1/jsp-2.1.jar +0 -0
  85. data/solr/lib/jsp-2.1/jsp-api-2.1.jar +0 -0
  86. data/solr/lib/servlet-api-2.4.jar +0 -0
  87. data/solr/lib/servlet-api-2.5-6.1.3.jar +0 -0
  88. data/solr/lib/xpp3-1.1.3.4.O.jar +0 -0
  89. data/solr/logs/.empty-dir-for-git +0 -0
  90. data/solr/solr/README.txt +52 -0
  91. data/solr/solr/bin/abc +176 -0
  92. data/solr/solr/bin/abo +176 -0
  93. data/solr/solr/bin/backup +108 -0
  94. data/solr/solr/bin/backupcleaner +142 -0
  95. data/solr/solr/bin/commit +128 -0
  96. data/solr/solr/bin/optimize +129 -0
  97. data/solr/solr/bin/readercycle +129 -0
  98. data/solr/solr/bin/rsyncd-disable +77 -0
  99. data/solr/solr/bin/rsyncd-enable +76 -0
  100. data/solr/solr/bin/rsyncd-start +145 -0
  101. data/solr/solr/bin/rsyncd-stop +105 -0
  102. data/solr/solr/bin/scripts-util +83 -0
  103. data/solr/solr/bin/snapcleaner +148 -0
  104. data/solr/solr/bin/snapinstaller +168 -0
  105. data/solr/solr/bin/snappuller +248 -0
  106. data/solr/solr/bin/snappuller-disable +77 -0
  107. data/solr/solr/bin/snappuller-enable +77 -0
  108. data/solr/solr/bin/snapshooter +109 -0
  109. data/solr/solr/conf/admin-extra.html +31 -0
  110. data/solr/solr/conf/protwords.txt +21 -0
  111. data/solr/solr/conf/schema.xml +126 -0
  112. data/solr/solr/conf/scripts.conf +24 -0
  113. data/solr/solr/conf/solrconfig.xml +458 -0
  114. data/solr/solr/conf/stopwords.txt +57 -0
  115. data/solr/solr/conf/synonyms.txt +31 -0
  116. data/solr/solr/conf/xslt/example.xsl +132 -0
  117. data/solr/solr/conf/xslt/example_atom.xsl +63 -0
  118. data/solr/solr/conf/xslt/example_rss.xsl +62 -0
  119. data/solr/start.jar +0 -0
  120. data/solr/tmp/.empty-dir-for-git +0 -0
  121. data/solr/webapps/solr.war +0 -0
  122. data/test/config/solr.yml +2 -0
  123. data/test/db/connections/mysql/connection.rb +10 -0
  124. data/test/db/connections/sqlite/connection.rb +8 -0
  125. data/test/db/migrate/001_create_books.rb +15 -0
  126. data/test/db/migrate/002_create_movies.rb +12 -0
  127. data/test/db/migrate/003_create_categories.rb +11 -0
  128. data/test/db/migrate/004_create_electronics.rb +16 -0
  129. data/test/db/migrate/005_create_authors.rb +12 -0
  130. data/test/db/migrate/006_create_postings.rb +9 -0
  131. data/test/db/migrate/007_create_posts.rb +13 -0
  132. data/test/db/migrate/008_create_gadgets.rb +11 -0
  133. data/test/fixtures/authors.yml +9 -0
  134. data/test/fixtures/books.yml +13 -0
  135. data/test/fixtures/categories.yml +7 -0
  136. data/test/fixtures/db_definitions/mysql.sql +41 -0
  137. data/test/fixtures/electronics.yml +49 -0
  138. data/test/fixtures/movies.yml +9 -0
  139. data/test/fixtures/postings.yml +10 -0
  140. data/test/functional/acts_as_solr_test.rb +413 -0
  141. data/test/functional/association_indexing_test.rb +37 -0
  142. data/test/functional/faceted_search_test.rb +163 -0
  143. data/test/functional/multi_solr_search_test.rb +51 -0
  144. data/test/models/author.rb +10 -0
  145. data/test/models/book.rb +10 -0
  146. data/test/models/category.rb +8 -0
  147. data/test/models/electronic.rb +21 -0
  148. data/test/models/gadget.rb +9 -0
  149. data/test/models/movie.rb +17 -0
  150. data/test/models/novel.rb +2 -0
  151. data/test/models/post.rb +3 -0
  152. data/test/models/posting.rb +11 -0
  153. data/test/test_helper.rb +51 -0
  154. data/test/unit/acts_methods_shoulda.rb +70 -0
  155. data/test/unit/class_methods_shoulda.rb +90 -0
  156. data/test/unit/common_methods_shoulda.rb +112 -0
  157. data/test/unit/instance_methods_shoulda.rb +326 -0
  158. data/test/unit/lazy_document_shoulda.rb +35 -0
  159. data/test/unit/parser_instance.rb +19 -0
  160. data/test/unit/parser_methods_shoulda.rb +279 -0
  161. data/test/unit/solr_instance.rb +46 -0
  162. data/test/unit/test_helper.rb +26 -0
  163. metadata +259 -0
@@ -0,0 +1,237 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{acts_as_solr}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kyle Maxwell"]
12
+ s.date = %q{2009-10-18}
13
+ s.description = %q{Acts As Solr}
14
+ s.email = %q{kyle@onemorecloud.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".gitignore",
22
+ "CHANGE_LOG",
23
+ "FORKED_CHANGES",
24
+ "LICENSE",
25
+ "README.markdown",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "TESTING_THE_PLUGIN",
29
+ "VERSION",
30
+ "acts_as_solr.gemspec",
31
+ "config/solr.yml",
32
+ "config/solr_environment.rb",
33
+ "init.rb",
34
+ "install.rb",
35
+ "lib/acts_as_solr.rb",
36
+ "lib/acts_methods.rb",
37
+ "lib/class_methods.rb",
38
+ "lib/common_methods.rb",
39
+ "lib/deprecation.rb",
40
+ "lib/instance_methods.rb",
41
+ "lib/lazy_document.rb",
42
+ "lib/parser_methods.rb",
43
+ "lib/search_results.rb",
44
+ "lib/solr.rb",
45
+ "lib/solr/connection.rb",
46
+ "lib/solr/document.rb",
47
+ "lib/solr/exception.rb",
48
+ "lib/solr/field.rb",
49
+ "lib/solr/importer.rb",
50
+ "lib/solr/importer/array_mapper.rb",
51
+ "lib/solr/importer/delimited_file_source.rb",
52
+ "lib/solr/importer/hpricot_mapper.rb",
53
+ "lib/solr/importer/mapper.rb",
54
+ "lib/solr/importer/solr_source.rb",
55
+ "lib/solr/importer/xpath_mapper.rb",
56
+ "lib/solr/indexer.rb",
57
+ "lib/solr/request.rb",
58
+ "lib/solr/request/add_document.rb",
59
+ "lib/solr/request/base.rb",
60
+ "lib/solr/request/commit.rb",
61
+ "lib/solr/request/delete.rb",
62
+ "lib/solr/request/dismax.rb",
63
+ "lib/solr/request/index_info.rb",
64
+ "lib/solr/request/modify_document.rb",
65
+ "lib/solr/request/optimize.rb",
66
+ "lib/solr/request/ping.rb",
67
+ "lib/solr/request/select.rb",
68
+ "lib/solr/request/spellcheck.rb",
69
+ "lib/solr/request/standard.rb",
70
+ "lib/solr/request/update.rb",
71
+ "lib/solr/response.rb",
72
+ "lib/solr/response/add_document.rb",
73
+ "lib/solr/response/base.rb",
74
+ "lib/solr/response/commit.rb",
75
+ "lib/solr/response/delete.rb",
76
+ "lib/solr/response/dismax.rb",
77
+ "lib/solr/response/index_info.rb",
78
+ "lib/solr/response/modify_document.rb",
79
+ "lib/solr/response/optimize.rb",
80
+ "lib/solr/response/ping.rb",
81
+ "lib/solr/response/ruby.rb",
82
+ "lib/solr/response/select.rb",
83
+ "lib/solr/response/spellcheck.rb",
84
+ "lib/solr/response/standard.rb",
85
+ "lib/solr/response/xml.rb",
86
+ "lib/solr/solrtasks.rb",
87
+ "lib/solr/util.rb",
88
+ "lib/solr/xml.rb",
89
+ "lib/solr_fixtures.rb",
90
+ "lib/tasks/database.rake",
91
+ "lib/tasks/solr.rake",
92
+ "lib/tasks/test.rake",
93
+ "lib/will_paginate_support.rb",
94
+ "solr/CHANGES.txt",
95
+ "solr/LICENSE.txt",
96
+ "solr/NOTICE.txt",
97
+ "solr/etc/jetty.xml",
98
+ "solr/etc/webdefault.xml",
99
+ "solr/lib/easymock.jar",
100
+ "solr/lib/jetty-6.1.3.jar",
101
+ "solr/lib/jetty-util-6.1.3.jar",
102
+ "solr/lib/jsp-2.1/ant-1.6.5.jar",
103
+ "solr/lib/jsp-2.1/core-3.1.1.jar",
104
+ "solr/lib/jsp-2.1/jsp-2.1.jar",
105
+ "solr/lib/jsp-2.1/jsp-api-2.1.jar",
106
+ "solr/lib/servlet-api-2.4.jar",
107
+ "solr/lib/servlet-api-2.5-6.1.3.jar",
108
+ "solr/lib/xpp3-1.1.3.4.O.jar",
109
+ "solr/logs/.empty-dir-for-git",
110
+ "solr/solr/README.txt",
111
+ "solr/solr/bin/abc",
112
+ "solr/solr/bin/abo",
113
+ "solr/solr/bin/backup",
114
+ "solr/solr/bin/backupcleaner",
115
+ "solr/solr/bin/commit",
116
+ "solr/solr/bin/optimize",
117
+ "solr/solr/bin/readercycle",
118
+ "solr/solr/bin/rsyncd-disable",
119
+ "solr/solr/bin/rsyncd-enable",
120
+ "solr/solr/bin/rsyncd-start",
121
+ "solr/solr/bin/rsyncd-stop",
122
+ "solr/solr/bin/scripts-util",
123
+ "solr/solr/bin/snapcleaner",
124
+ "solr/solr/bin/snapinstaller",
125
+ "solr/solr/bin/snappuller",
126
+ "solr/solr/bin/snappuller-disable",
127
+ "solr/solr/bin/snappuller-enable",
128
+ "solr/solr/bin/snapshooter",
129
+ "solr/solr/conf/admin-extra.html",
130
+ "solr/solr/conf/protwords.txt",
131
+ "solr/solr/conf/schema.xml",
132
+ "solr/solr/conf/scripts.conf",
133
+ "solr/solr/conf/solrconfig.xml",
134
+ "solr/solr/conf/stopwords.txt",
135
+ "solr/solr/conf/synonyms.txt",
136
+ "solr/solr/conf/xslt/example.xsl",
137
+ "solr/solr/conf/xslt/example_atom.xsl",
138
+ "solr/solr/conf/xslt/example_rss.xsl",
139
+ "solr/start.jar",
140
+ "solr/tmp/.empty-dir-for-git",
141
+ "solr/webapps/solr.war",
142
+ "test/config/solr.yml",
143
+ "test/db/connections/mysql/connection.rb",
144
+ "test/db/connections/sqlite/connection.rb",
145
+ "test/db/migrate/001_create_books.rb",
146
+ "test/db/migrate/002_create_movies.rb",
147
+ "test/db/migrate/003_create_categories.rb",
148
+ "test/db/migrate/004_create_electronics.rb",
149
+ "test/db/migrate/005_create_authors.rb",
150
+ "test/db/migrate/006_create_postings.rb",
151
+ "test/db/migrate/007_create_posts.rb",
152
+ "test/db/migrate/008_create_gadgets.rb",
153
+ "test/fixtures/authors.yml",
154
+ "test/fixtures/books.yml",
155
+ "test/fixtures/categories.yml",
156
+ "test/fixtures/db_definitions/mysql.sql",
157
+ "test/fixtures/electronics.yml",
158
+ "test/fixtures/movies.yml",
159
+ "test/fixtures/postings.yml",
160
+ "test/functional/acts_as_solr_test.rb",
161
+ "test/functional/association_indexing_test.rb",
162
+ "test/functional/faceted_search_test.rb",
163
+ "test/functional/multi_solr_search_test.rb",
164
+ "test/models/author.rb",
165
+ "test/models/book.rb",
166
+ "test/models/category.rb",
167
+ "test/models/electronic.rb",
168
+ "test/models/gadget.rb",
169
+ "test/models/movie.rb",
170
+ "test/models/novel.rb",
171
+ "test/models/post.rb",
172
+ "test/models/posting.rb",
173
+ "test/test_helper.rb",
174
+ "test/unit/acts_methods_shoulda.rb",
175
+ "test/unit/class_methods_shoulda.rb",
176
+ "test/unit/common_methods_shoulda.rb",
177
+ "test/unit/instance_methods_shoulda.rb",
178
+ "test/unit/lazy_document_shoulda.rb",
179
+ "test/unit/parser_instance.rb",
180
+ "test/unit/parser_methods_shoulda.rb",
181
+ "test/unit/solr_instance.rb",
182
+ "test/unit/test_helper.rb"
183
+ ]
184
+ s.homepage = %q{http://github.com/onemorecloud/acts_as_solr}
185
+ s.rdoc_options = ["--charset=UTF-8"]
186
+ s.require_paths = ["lib"]
187
+ s.rubygems_version = %q{1.3.4}
188
+ s.summary = %q{Solr integration for rails}
189
+ s.test_files = [
190
+ "test/db/connections/mysql/connection.rb",
191
+ "test/db/connections/sqlite/connection.rb",
192
+ "test/db/migrate/001_create_books.rb",
193
+ "test/db/migrate/002_create_movies.rb",
194
+ "test/db/migrate/003_create_categories.rb",
195
+ "test/db/migrate/004_create_electronics.rb",
196
+ "test/db/migrate/005_create_authors.rb",
197
+ "test/db/migrate/006_create_postings.rb",
198
+ "test/db/migrate/007_create_posts.rb",
199
+ "test/db/migrate/008_create_gadgets.rb",
200
+ "test/functional/acts_as_solr_test.rb",
201
+ "test/functional/association_indexing_test.rb",
202
+ "test/functional/faceted_search_test.rb",
203
+ "test/functional/multi_solr_search_test.rb",
204
+ "test/models/author.rb",
205
+ "test/models/book.rb",
206
+ "test/models/category.rb",
207
+ "test/models/electronic.rb",
208
+ "test/models/gadget.rb",
209
+ "test/models/movie.rb",
210
+ "test/models/novel.rb",
211
+ "test/models/post.rb",
212
+ "test/models/posting.rb",
213
+ "test/test_helper.rb",
214
+ "test/unit/acts_methods_shoulda.rb",
215
+ "test/unit/class_methods_shoulda.rb",
216
+ "test/unit/common_methods_shoulda.rb",
217
+ "test/unit/instance_methods_shoulda.rb",
218
+ "test/unit/lazy_document_shoulda.rb",
219
+ "test/unit/parser_instance.rb",
220
+ "test/unit/parser_methods_shoulda.rb",
221
+ "test/unit/solr_instance.rb",
222
+ "test/unit/test_helper.rb"
223
+ ]
224
+
225
+ if s.respond_to? :specification_version then
226
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
227
+ s.specification_version = 3
228
+
229
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
230
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
231
+ else
232
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
233
+ end
234
+ else
235
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
236
+ end
237
+ end
data/config/solr.yml ADDED
@@ -0,0 +1,15 @@
1
+ # Config file for the acts_as_solr plugin.
2
+ #
3
+ # If you change the host or port number here, make sure you update
4
+ # them in your Solr config file
5
+
6
+ development:
7
+ url: http://127.0.0.1:8982/solr
8
+
9
+ production:
10
+ url: http://127.0.0.1:8983/solr
11
+ jvm_options: -server -d64 -Xmx1024M -Xms64M
12
+
13
+ test:
14
+ url: http://127.0.0.1:8981/solr
15
+
@@ -0,0 +1,22 @@
1
+ ENV['RAILS_ENV'] = (ENV['RAILS_ENV'] || 'development').dup
2
+ # RAILS_ROOT isn't defined yet, so figure it out.
3
+ rails_root_dir = "#{File.dirname(File.expand_path(__FILE__))}/../../../../"
4
+ SOLR_PATH = "#{File.dirname(File.expand_path(__FILE__))}/../solr" unless defined? SOLR_PATH
5
+
6
+ SOLR_LOGS_PATH = "#{rails_root_dir}/log" unless defined? SOLR_LOGS_PATH
7
+ SOLR_PIDS_PATH = "#{rails_root_dir}/tmp/pids" unless defined? SOLR_PIDS_PATH
8
+ SOLR_DATA_PATH = "#{rails_root_dir}/solr/#{ENV['RAILS_ENV']}" unless defined? SOLR_DATA_PATH
9
+
10
+ unless defined? SOLR_PORT
11
+ config = YAML::load_file(rails_root_dir+'/config/solr.yml')
12
+
13
+ SOLR_PORT = ENV['PORT'] || URI.parse(config[ENV['RAILS_ENV']]['url']).port
14
+ end
15
+
16
+ SOLR_JVM_OPTIONS = config[ENV['RAILS_ENV']]['jvm_options'] unless defined? SOLR_JVM_OPTIONS
17
+
18
+ if ENV['RAILS_ENV'] == 'test'
19
+ DB = (ENV['DB'] ? ENV['DB'] : 'mysql') unless defined?(DB)
20
+ MYSQL_USER = (ENV['MYSQL_USER'].nil? ? 'root' : ENV['MYSQL_USER']) unless defined? MYSQL_USER
21
+ require File.join(File.dirname(File.expand_path(__FILE__)), '..', 'test', 'db', 'connections', DB, 'connection.rb')
22
+ end
data/init.rb ADDED
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2006 Erik Hatcher, Thiago Jackiw
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'acts_as_solr'
data/install.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'fileutils'
2
+
3
+ def install(file)
4
+ puts "Installing: #{file}"
5
+ target = File.join(File.dirname(__FILE__), '..', '..', '..', file)
6
+ FileUtils.cp File.join(File.dirname(__FILE__), file), target
7
+ dir_to_rename = File.dirname(__FILE__) + '/../trunk'
8
+ FileUtils.mv(dir_to_rename, File.dirname(__FILE__) + '/../acts_as_solr') if File.exists? dir_to_rename
9
+ end
10
+
11
+ install File.join( 'config', 'solr.yml' )
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2006 Erik Hatcher, Thiago Jackiw
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'active_record'
22
+ require 'rexml/document'
23
+ require 'net/http'
24
+ require 'yaml'
25
+
26
+ require File.dirname(__FILE__) + '/solr'
27
+ require File.dirname(__FILE__) + '/acts_methods'
28
+ require File.dirname(__FILE__) + '/class_methods'
29
+ require File.dirname(__FILE__) + '/instance_methods'
30
+ require File.dirname(__FILE__) + '/common_methods'
31
+ require File.dirname(__FILE__) + '/deprecation'
32
+ require File.dirname(__FILE__) + '/search_results'
33
+ require File.dirname(__FILE__) + '/lazy_document'
34
+ require File.dirname(__FILE__) + '/will_paginate_support'
35
+ module ActsAsSolr
36
+ class ConnectionError < RuntimeError; end
37
+
38
+ class Post
39
+ def self.execute(request)
40
+ begin
41
+ if File.exists?(RAILS_ROOT+'/config/solr.yml')
42
+ config = YAML::load_file(RAILS_ROOT+'/config/solr.yml')
43
+ url = config[RAILS_ENV]['url']
44
+ # for backwards compatibility
45
+ url ||= "http://#{config[RAILS_ENV]['host']}:#{config[RAILS_ENV]['port']}/#{config[RAILS_ENV]['servlet_path']}"
46
+ else
47
+ url = 'http://localhost:8982/solr'
48
+ end
49
+ connection = Solr::Connection.new(url)
50
+ return connection.send(request)
51
+ rescue
52
+ raise ActsAsSolr::ConnectionError, "Couldn't connect to the Solr server at #{url}. #{$!}"
53
+ false
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ # reopen ActiveRecord and include the acts_as_solr method
61
+ ActiveRecord::Base.extend ActsAsSolr::ActsMethods
@@ -0,0 +1,284 @@
1
+ module ActsAsSolr #:nodoc:
2
+
3
+ module ActsMethods
4
+
5
+ # declares a class as solr-searchable
6
+ #
7
+ # ==== options:
8
+ # fields:: This option can be used to specify only the fields you'd
9
+ # like to index. If not given, all the attributes from the
10
+ # class will be indexed. You can also use this option to
11
+ # include methods that should be indexed as fields
12
+ #
13
+ # class Movie < ActiveRecord::Base
14
+ # acts_as_solr :fields => [:name, :description, :current_time]
15
+ # def current_time
16
+ # Time.now.to_s
17
+ # end
18
+ # end
19
+ #
20
+ # Each field passed can also be a hash with the value being a field type
21
+ #
22
+ # class Electronic < ActiveRecord::Base
23
+ # acts_as_solr :fields => [{:price => :range_float}]
24
+ # def current_time
25
+ # Time.now
26
+ # end
27
+ # end
28
+ #
29
+ # The field types accepted are:
30
+ #
31
+ # :float:: Index the field value as a float (ie.: 12.87)
32
+ # :integer:: Index the field value as an integer (ie.: 31)
33
+ # :boolean:: Index the field value as a boolean (ie.: true/false)
34
+ # :date:: Index the field value as a date (ie.: Wed Nov 15 23:13:03 PST 2006)
35
+ # :string:: Index the field value as a text string, not applying the same indexing
36
+ # filters as a regular text field
37
+ # :range_integer:: Index the field value for integer range queries (ie.:[5 TO 20])
38
+ # :range_float:: Index the field value for float range queries (ie.:[14.56 TO 19.99])
39
+ #
40
+ # Setting the field type preserves its original type when indexed
41
+ #
42
+ # The field may also be passed with a hash value containing options
43
+ #
44
+ # class Author < ActiveRecord::Base
45
+ # acts_as_solr :fields => [{:full_name => {:type => :text, :as => :name}}]
46
+ # def full_name
47
+ # self.first_name + ' ' + self.last_name
48
+ # end
49
+ # end
50
+ #
51
+ # The options accepted are:
52
+ #
53
+ # :type:: Index the field using the specified type
54
+ # :as:: Index the field using the specified field name
55
+ #
56
+ # additional_fields:: This option takes fields to be include in the index
57
+ # in addition to those derived from the database. You
58
+ # can also use this option to include custom fields
59
+ # derived from methods you define. This option will be
60
+ # ignored if the :fields option is given. It also accepts
61
+ # the same field types as the option above
62
+ #
63
+ # class Movie < ActiveRecord::Base
64
+ # acts_as_solr :additional_fields => [:current_time]
65
+ # def current_time
66
+ # Time.now.to_s
67
+ # end
68
+ # end
69
+ #
70
+ # exclude_fields:: This option taks an array of fields that should be ignored from indexing:
71
+ #
72
+ # class User < ActiveRecord::Base
73
+ # acts_as_solr :exclude_fields => [:password, :login, :credit_card_number]
74
+ # end
75
+ #
76
+ # include:: This option can be used for association indexing, which
77
+ # means you can include any :has_one, :has_many, :belongs_to
78
+ # and :has_and_belongs_to_many association to be indexed:
79
+ #
80
+ # class Category < ActiveRecord::Base
81
+ # has_many :books
82
+ # acts_as_solr :include => [:books]
83
+ # end
84
+ #
85
+ # Each association may also be specified as a hash with an option hash as a value
86
+ #
87
+ # class Book < ActiveRecord::Base
88
+ # belongs_to :author
89
+ # has_many :distribution_companies
90
+ # has_many :copyright_dates
91
+ # has_many :media_types
92
+ # acts_as_solr(
93
+ # :fields => [:name, :description],
94
+ # :include => [
95
+ # {:author => {:using => :fullname, :as => :name}},
96
+ # {:media_types => {:using => lambda{|media| type_lookup(media.id)}}}
97
+ # {:distribution_companies => {:as => :distributor, :multivalued => true}},
98
+ # {:copyright_dates => {:as => :copyright, :type => :date}}
99
+ # ]
100
+ # ]
101
+ #
102
+ # The options accepted are:
103
+ #
104
+ # :type:: Index the associated objects using the specified type
105
+ # :as:: Index the associated objects using the specified field name
106
+ # :using:: Index the associated objects using the value returned by the specified method or proc. If a method
107
+ # symbol is supplied, it will be sent to each object to look up the value to index; if a proc is
108
+ # supplied, it will be called once for each object with the object as the only argument
109
+ # :multivalued:: Index the associated objects using one field for each object rather than joining them
110
+ # all into a single field
111
+ #
112
+ # facets:: This option can be used to specify the fields you'd like to
113
+ # index as facet fields
114
+ #
115
+ # class Electronic < ActiveRecord::Base
116
+ # acts_as_solr :facets => [:category, :manufacturer]
117
+ # end
118
+ #
119
+ # boost:: You can pass a boost (float) value that will be used to boost the document and/or a field. To specify a more
120
+ # boost for the document, you can either pass a block or a symbol. The block will be called with the record
121
+ # as an argument, a symbol will result in the according method being called:
122
+ #
123
+ # class Electronic < ActiveRecord::Base
124
+ # acts_as_solr :fields => [{:price => {:boost => 5.0}}], :boost => 10.0
125
+ # end
126
+ #
127
+ # class Electronic < ActiveRecord::Base
128
+ # acts_as_solr :fields => [{:price => {:boost => 5.0}}], :boost => proc {|record| record.id + 120*37}
129
+ # end
130
+ #
131
+ # class Electronic < ActiveRecord::Base
132
+ # acts_as_solr :fields => [{:price => {:boost => :price_rating}}], :boost => 10.0
133
+ # end
134
+ #
135
+ # if:: Only indexes the record if the condition evaluated is true. The argument has to be
136
+ # either a symbol, string (to be eval'ed), proc/method, or class implementing a static
137
+ # validation method. It behaves the same way as ActiveRecord's :if option.
138
+ #
139
+ # class Electronic < ActiveRecord::Base
140
+ # acts_as_solr :if => proc{|record| record.is_active?}
141
+ # end
142
+ #
143
+ # offline:: Assumes that your using an outside mechanism to explicitly trigger indexing records, e.g. you only
144
+ # want to update your index through some asynchronous mechanism. Will accept either a boolean or a block
145
+ # that will be evaluated before actually contacting the index for saving or destroying a document. Defaults
146
+ # to false. It doesn't refer to the mechanism of an offline index in general, but just to get a centralized point
147
+ # where you can control indexing. Note: This is only enabled for saving records. acts_as_solr doesn't always like
148
+ # it, if you have a different number of results coming from the database and the index. This might be rectified in
149
+ # another patch to support lazy loading.
150
+ #
151
+ # class Electronic < ActiveRecord::Base
152
+ # acts_as_solr :offline => proc {|record| record.automatic_indexing_disabled?}
153
+ # end
154
+ #
155
+ # auto_commit:: The commit command will be sent to Solr only if its value is set to true:
156
+ #
157
+ # class Author < ActiveRecord::Base
158
+ # acts_as_solr :auto_commit => false
159
+ # end
160
+ #
161
+ def acts_as_solr(options={}, solr_options={})
162
+
163
+ extend ClassMethods
164
+ include InstanceMethods
165
+ include CommonMethods
166
+ include ParserMethods
167
+
168
+ cattr_accessor :configuration
169
+ cattr_accessor :solr_configuration
170
+
171
+ self.configuration = {
172
+ :fields => nil,
173
+ :additional_fields => nil,
174
+ :exclude_fields => [],
175
+ :auto_commit => true,
176
+ :include => nil,
177
+ :facets => nil,
178
+ :boost => nil,
179
+ :if => "true",
180
+ :offline => false
181
+ }
182
+ self.solr_configuration = {
183
+ :type_field => "type_s",
184
+ :primary_key_field => "pk_i",
185
+ :default_boost => 1.0
186
+ }
187
+
188
+ configuration.update(options) if options.is_a?(Hash)
189
+ solr_configuration.update(solr_options) if solr_options.is_a?(Hash)
190
+ Deprecation.validate_index(configuration)
191
+
192
+ configuration[:solr_fields] = {}
193
+ configuration[:solr_includes] = {}
194
+
195
+ after_save :solr_save
196
+ after_destroy :solr_destroy
197
+
198
+ if configuration[:fields].respond_to?(:each)
199
+ process_fields(configuration[:fields])
200
+ else
201
+ process_fields(self.new.attributes.keys.map { |k| k.to_sym })
202
+ process_fields(configuration[:additional_fields])
203
+ end
204
+
205
+ if configuration[:include].respond_to?(:each)
206
+ process_includes(configuration[:include])
207
+ end
208
+
209
+ unless @already_solr_magic
210
+ alias_method_chain :method_missing, :solr_magic
211
+ @already_solr_magic = true
212
+ end
213
+ end
214
+
215
+ private
216
+ def get_field_value(field)
217
+ field_name, options = determine_field_name_and_options(field)
218
+ configuration[:solr_fields][field_name] = options
219
+
220
+ define_method("#{field_name}_for_solr".to_sym) do
221
+ begin
222
+ value = self[field_name] || self.instance_variable_get("@#{field_name.to_s}".to_sym) || self.send(field_name.to_sym)
223
+ case options[:type]
224
+ # format dates properly; return nil for nil dates
225
+ when :date
226
+ value ? (value.respond_to?(:utc) ? value.utc : value).strftime("%Y-%m-%dT%H:%M:%SZ") : nil
227
+ else value
228
+ end
229
+ rescue
230
+ puts $!
231
+ logger.debug "There was a problem getting the value for the field '#{field_name}': #{$!}"
232
+ value = ''
233
+ end
234
+ end
235
+ end
236
+
237
+ def process_fields(raw_field)
238
+ if raw_field.respond_to?(:each)
239
+ raw_field.each do |field|
240
+ next if configuration[:exclude_fields].include?(field)
241
+ get_field_value(field)
242
+ end
243
+ end
244
+ end
245
+
246
+ def process_includes(includes)
247
+ if includes.respond_to?(:each)
248
+ includes.each do |assoc|
249
+ field_name, options = determine_field_name_and_options(assoc)
250
+ configuration[:solr_includes][field_name] = options
251
+ end
252
+ end
253
+ end
254
+
255
+ def determine_field_name_and_options(field)
256
+ if field.is_a?(Hash)
257
+ name = field.keys.first
258
+ options = field.values.first
259
+ if options.is_a?(Hash)
260
+ [name, {:type => type_for_field(field)}.merge(options)]
261
+ else
262
+ [name, {:type => options}]
263
+ end
264
+ else
265
+ [field, {:type => type_for_field(field)}]
266
+ end
267
+ end
268
+
269
+ def type_for_field(field)
270
+ if configuration[:facets] && configuration[:facets].include?(field)
271
+ :facet
272
+ elsif column = columns_hash[field.to_s]
273
+ case column.type
274
+ when :string then :text
275
+ when :datetime then :date
276
+ when :time then :date
277
+ else column.type
278
+ end
279
+ else
280
+ :text
281
+ end
282
+ end
283
+ end
284
+ end