acts_as_solr 1.0.0

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