gojee-sunspot 2.0.3 → 2.0.4

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 (178) hide show
  1. data/.gitignore +12 -0
  2. data/Gemfile +5 -0
  3. data/History.txt +252 -0
  4. data/LICENSE +18 -0
  5. data/Rakefile +13 -0
  6. data/TODO +13 -0
  7. data/lib/light_config.rb +40 -0
  8. data/lib/sunspot/adapters.rb +265 -0
  9. data/lib/sunspot/batcher.rb +62 -0
  10. data/lib/sunspot/class_set.rb +23 -0
  11. data/lib/sunspot/composite_setup.rb +202 -0
  12. data/lib/sunspot/configuration.rb +53 -0
  13. data/lib/sunspot/data_extractor.rb +50 -0
  14. data/lib/sunspot/dsl/adjustable.rb +47 -0
  15. data/lib/sunspot/dsl/field_group.rb +57 -0
  16. data/lib/sunspot/dsl/field_query.rb +327 -0
  17. data/lib/sunspot/dsl/fields.rb +103 -0
  18. data/lib/sunspot/dsl/fulltext.rb +243 -0
  19. data/lib/sunspot/dsl/function.rb +27 -0
  20. data/lib/sunspot/dsl/functional.rb +44 -0
  21. data/lib/sunspot/dsl/more_like_this_query.rb +56 -0
  22. data/lib/sunspot/dsl/paginatable.rb +32 -0
  23. data/lib/sunspot/dsl/query_facet.rb +36 -0
  24. data/lib/sunspot/dsl/restriction.rb +25 -0
  25. data/lib/sunspot/dsl/restriction_with_near.rb +160 -0
  26. data/lib/sunspot/dsl/scope.rb +217 -0
  27. data/lib/sunspot/dsl/search.rb +30 -0
  28. data/lib/sunspot/dsl/standard_query.rb +123 -0
  29. data/lib/sunspot/dsl.rb +5 -0
  30. data/lib/sunspot/field.rb +193 -0
  31. data/lib/sunspot/field_factory.rb +129 -0
  32. data/lib/sunspot/indexer.rb +136 -0
  33. data/lib/sunspot/query/abstract_field_facet.rb +52 -0
  34. data/lib/sunspot/query/bbox.rb +15 -0
  35. data/lib/sunspot/query/boost_query.rb +24 -0
  36. data/lib/sunspot/query/common_query.rb +96 -0
  37. data/lib/sunspot/query/composite_fulltext.rb +36 -0
  38. data/lib/sunspot/query/connective.rb +206 -0
  39. data/lib/sunspot/query/date_field_facet.rb +14 -0
  40. data/lib/sunspot/query/dismax.rb +132 -0
  41. data/lib/sunspot/query/field_facet.rb +41 -0
  42. data/lib/sunspot/query/field_group.rb +36 -0
  43. data/lib/sunspot/query/filter.rb +38 -0
  44. data/lib/sunspot/query/function_query.rb +52 -0
  45. data/lib/sunspot/query/geo.rb +53 -0
  46. data/lib/sunspot/query/geofilt.rb +16 -0
  47. data/lib/sunspot/query/highlighting.rb +62 -0
  48. data/lib/sunspot/query/more_like_this.rb +61 -0
  49. data/lib/sunspot/query/more_like_this_query.rb +12 -0
  50. data/lib/sunspot/query/pagination.rb +42 -0
  51. data/lib/sunspot/query/query_facet.rb +16 -0
  52. data/lib/sunspot/query/restriction.rb +262 -0
  53. data/lib/sunspot/query/scope.rb +9 -0
  54. data/lib/sunspot/query/sort.rb +109 -0
  55. data/lib/sunspot/query/sort_composite.rb +34 -0
  56. data/lib/sunspot/query/standard_query.rb +16 -0
  57. data/lib/sunspot/query/text_field_boost.rb +17 -0
  58. data/lib/sunspot/query.rb +11 -0
  59. data/lib/sunspot/schema.rb +151 -0
  60. data/lib/sunspot/search/abstract_search.rb +281 -0
  61. data/lib/sunspot/search/date_facet.rb +35 -0
  62. data/lib/sunspot/search/facet_row.rb +27 -0
  63. data/lib/sunspot/search/field_facet.rb +88 -0
  64. data/lib/sunspot/search/field_group.rb +32 -0
  65. data/lib/sunspot/search/group.rb +50 -0
  66. data/lib/sunspot/search/highlight.rb +38 -0
  67. data/lib/sunspot/search/hit.rb +150 -0
  68. data/lib/sunspot/search/hit_enumerable.rb +72 -0
  69. data/lib/sunspot/search/more_like_this_search.rb +31 -0
  70. data/lib/sunspot/search/paginated_collection.rb +57 -0
  71. data/lib/sunspot/search/query_facet.rb +67 -0
  72. data/lib/sunspot/search/standard_search.rb +21 -0
  73. data/lib/sunspot/search.rb +9 -0
  74. data/lib/sunspot/session.rb +262 -0
  75. data/lib/sunspot/session_proxy/abstract_session_proxy.rb +29 -0
  76. data/lib/sunspot/session_proxy/class_sharding_session_proxy.rb +66 -0
  77. data/lib/sunspot/session_proxy/id_sharding_session_proxy.rb +89 -0
  78. data/lib/sunspot/session_proxy/master_slave_session_proxy.rb +43 -0
  79. data/lib/sunspot/session_proxy/multicore_session_proxy.rb +67 -0
  80. data/lib/sunspot/session_proxy/sharding_session_proxy.rb +222 -0
  81. data/lib/sunspot/session_proxy/silent_fail_session_proxy.rb +42 -0
  82. data/lib/sunspot/session_proxy/thread_local_session_proxy.rb +37 -0
  83. data/lib/sunspot/session_proxy.rb +95 -0
  84. data/lib/sunspot/setup.rb +350 -0
  85. data/lib/sunspot/text_field_setup.rb +29 -0
  86. data/lib/sunspot/type.rb +393 -0
  87. data/lib/sunspot/util.rb +252 -0
  88. data/lib/sunspot/version.rb +3 -0
  89. data/lib/sunspot.rb +579 -0
  90. data/log/.gitignore +1 -0
  91. data/pkg/.gitignore +1 -0
  92. data/script/console +10 -0
  93. data/spec/api/adapters_spec.rb +33 -0
  94. data/spec/api/batcher_spec.rb +112 -0
  95. data/spec/api/binding_spec.rb +50 -0
  96. data/spec/api/class_set_spec.rb +24 -0
  97. data/spec/api/hit_enumerable_spec.rb +47 -0
  98. data/spec/api/indexer/attributes_spec.rb +149 -0
  99. data/spec/api/indexer/batch_spec.rb +72 -0
  100. data/spec/api/indexer/dynamic_fields_spec.rb +42 -0
  101. data/spec/api/indexer/fixed_fields_spec.rb +57 -0
  102. data/spec/api/indexer/fulltext_spec.rb +43 -0
  103. data/spec/api/indexer/removal_spec.rb +53 -0
  104. data/spec/api/indexer/spec_helper.rb +1 -0
  105. data/spec/api/indexer_spec.rb +14 -0
  106. data/spec/api/query/advanced_manipulation_examples.rb +35 -0
  107. data/spec/api/query/connectives_examples.rb +189 -0
  108. data/spec/api/query/dsl_spec.rb +18 -0
  109. data/spec/api/query/dynamic_fields_examples.rb +165 -0
  110. data/spec/api/query/faceting_examples.rb +397 -0
  111. data/spec/api/query/fulltext_examples.rb +313 -0
  112. data/spec/api/query/function_spec.rb +79 -0
  113. data/spec/api/query/geo_examples.rb +68 -0
  114. data/spec/api/query/group_spec.rb +32 -0
  115. data/spec/api/query/highlighting_examples.rb +245 -0
  116. data/spec/api/query/more_like_this_spec.rb +140 -0
  117. data/spec/api/query/ordering_pagination_examples.rb +116 -0
  118. data/spec/api/query/scope_examples.rb +275 -0
  119. data/spec/api/query/spatial_examples.rb +27 -0
  120. data/spec/api/query/spec_helper.rb +1 -0
  121. data/spec/api/query/standard_spec.rb +29 -0
  122. data/spec/api/query/text_field_scoping_examples.rb +30 -0
  123. data/spec/api/query/types_spec.rb +20 -0
  124. data/spec/api/search/dynamic_fields_spec.rb +33 -0
  125. data/spec/api/search/faceting_spec.rb +360 -0
  126. data/spec/api/search/highlighting_spec.rb +69 -0
  127. data/spec/api/search/hits_spec.rb +131 -0
  128. data/spec/api/search/paginated_collection_spec.rb +36 -0
  129. data/spec/api/search/results_spec.rb +72 -0
  130. data/spec/api/search/search_spec.rb +23 -0
  131. data/spec/api/search/spec_helper.rb +1 -0
  132. data/spec/api/session_proxy/class_sharding_session_proxy_spec.rb +85 -0
  133. data/spec/api/session_proxy/id_sharding_session_proxy_spec.rb +30 -0
  134. data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +41 -0
  135. data/spec/api/session_proxy/sharding_session_proxy_spec.rb +77 -0
  136. data/spec/api/session_proxy/silent_fail_session_proxy_spec.rb +24 -0
  137. data/spec/api/session_proxy/spec_helper.rb +9 -0
  138. data/spec/api/session_proxy/thread_local_session_proxy_spec.rb +39 -0
  139. data/spec/api/session_spec.rb +232 -0
  140. data/spec/api/spec_helper.rb +3 -0
  141. data/spec/api/sunspot_spec.rb +29 -0
  142. data/spec/ext.rb +11 -0
  143. data/spec/helpers/indexer_helper.rb +17 -0
  144. data/spec/helpers/integration_helper.rb +8 -0
  145. data/spec/helpers/mock_session_helper.rb +13 -0
  146. data/spec/helpers/query_helper.rb +26 -0
  147. data/spec/helpers/search_helper.rb +68 -0
  148. data/spec/integration/dynamic_fields_spec.rb +57 -0
  149. data/spec/integration/faceting_spec.rb +251 -0
  150. data/spec/integration/field_grouping_spec.rb +66 -0
  151. data/spec/integration/geospatial_spec.rb +85 -0
  152. data/spec/integration/highlighting_spec.rb +44 -0
  153. data/spec/integration/indexing_spec.rb +55 -0
  154. data/spec/integration/keyword_search_spec.rb +317 -0
  155. data/spec/integration/local_search_spec.rb +64 -0
  156. data/spec/integration/more_like_this_spec.rb +43 -0
  157. data/spec/integration/scoped_search_spec.rb +354 -0
  158. data/spec/integration/stored_fields_spec.rb +12 -0
  159. data/spec/integration/test_pagination.rb +43 -0
  160. data/spec/integration/unicode_spec.rb +15 -0
  161. data/spec/mocks/adapters.rb +32 -0
  162. data/spec/mocks/blog.rb +3 -0
  163. data/spec/mocks/comment.rb +21 -0
  164. data/spec/mocks/connection.rb +126 -0
  165. data/spec/mocks/mock_adapter.rb +30 -0
  166. data/spec/mocks/mock_class_sharding_session_proxy.rb +24 -0
  167. data/spec/mocks/mock_record.rb +52 -0
  168. data/spec/mocks/mock_sharding_session_proxy.rb +15 -0
  169. data/spec/mocks/photo.rb +11 -0
  170. data/spec/mocks/post.rb +86 -0
  171. data/spec/mocks/super_class.rb +2 -0
  172. data/spec/mocks/user.rb +13 -0
  173. data/spec/spec_helper.rb +40 -0
  174. data/sunspot.gemspec +42 -0
  175. data/tasks/rdoc.rake +27 -0
  176. data/tasks/schema.rake +19 -0
  177. data/tasks/todo.rake +4 -0
  178. metadata +261 -3
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ sunspot-solr.pid
2
+ *.swp
3
+ coverage
4
+ pkg
5
+ /doc
6
+ .DS_Store
7
+
8
+ .yardoc
9
+ README.rdoc
10
+ .bundle
11
+ Gemfile.lock
12
+ *un~
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'sunspot_solr', :path => File.expand_path('../../sunspot_solr', __FILE__)
4
+
5
+ gemspec
data/History.txt ADDED
@@ -0,0 +1,252 @@
1
+ == 2.0.0
2
+ * Adds support for field grouping (Andy Lindeman)
3
+ * Adds support for native geospatial searches and ordering (Eric Tang, Bruno Miranda, Andy Lindeman)
4
+ * Bundled Solr installation (`sunspot_solr`) is version 3.5.0 (Chris Parker)
5
+ * Adds #query_time method to retrieve the Solr query time in
6
+ milliseconds (Jason Weathered)
7
+ * Fixes syntax of highlighting when used with nested dismax queries (Marco Crepaldi)
8
+ * Adds ability to nest `Sunspot.batch` calls (Thorbjørn Hermansen)
9
+ * Adds `open_timeout` and `read_timeout` configuration options (Rob Di
10
+ Marco)
11
+
12
+ == 1.3.0 2011-11-26
13
+ * Requests to Solr use HTTP POST verb by default to avoid issues when the query string grows too large for GET (Johan Van Ryseghem)
14
+ * `sunspot.yml` supports ERB (Andrew Cholakian)
15
+ * An error is raised when attempting to run the packaged Solr if Java is not available (Lucas Parry)
16
+ * Pagination operates correctly without dependency on `will_paginate` (Larry Sprock, Dave Krupinski)
17
+ * Stored boolean fields with `false` value are returned correctly (yipdw)
18
+ * `highlight` accepts `:formatter` and `:fragmenter` parameters (Jeremy McNevin)
19
+ * Default `headerBufferSize` is increased for packaged Solr make sure the limit is not reached during large queries (gjb83)
20
+ * Packaged Solr respects the `data_path` configuration setting from `sunspot.yml` (djmaze)
21
+ * Packaged Solr correctly uses the `pid_dir` configuration option from `sunspot.yml` (Russen Guggemos)
22
+ * Specs run correctly in 1.9.2 (Larry Sprock)
23
+ * Documentation improvements (Thibaut Barrère, gjb83, Breno Santos Salgado)
24
+ * Adds :offset option to paginate method (Benjamin Fleischer)
25
+ * Requires rsolr 1.0.6, which fixes issues with Unicode characters
26
+ returned by Solr
27
+
28
+ == 1.2.1 2010-12-28
29
+ * Decreased default reindexing batch size from 500 to 50
30
+
31
+ == 1.2.0 2010-12-28
32
+ * Replace solr-spatial-light with client-side geohash-based spatial search
33
+ * Override Solr field naming conventions using :as option
34
+ * Delegate #id method directly to calling context inside DSL
35
+ * Create a SilentFailSessionProxy that rescues exceptions on write operations.
36
+ * Inclusion by identity
37
+ * Solr optimize command
38
+ * Ignore negative :limit option for query facets
39
+ * Eliminated value sorting for range scopes
40
+ * Correctly cast stored boolean values if they are booleans
41
+ * Correctly cast and return stored values for multi-valued fields
42
+
43
+ == 1.1.0 2010-04-01
44
+ * MoreLikeThis support
45
+ * Allow multiple fulltext queries in one search
46
+ * Function queries
47
+ * Update solr-spatial-light to 0.0.6 build
48
+ * Support for :prefix when faceting.
49
+ * Allow specification of solr jar
50
+ * Updated reindex task to allow setting of batch size and list of models to index
51
+ * Use a '*:*' query for deleting the entire index
52
+ * Ability to specify custom request handler for queries
53
+ * Gracefully handle nonexistent search result
54
+
55
+ == 1.0.4 2010-03-19
56
+ * Update solr-spatial-light to 0.0.5
57
+ * Fix NullPointerException in repeated geo search
58
+ * Fix missing distances in repeated geo search
59
+ * Don't query the data store more than once when results are missing
60
+
61
+ == 1.0.2 2010-03-11
62
+ * Restore Hit#distance for result geo distance
63
+ * Remove :distance special sort
64
+ * Quote reserved keywords in boolean queries
65
+ * Add Search#facets accessor to retrieve all facets
66
+
67
+ == 1.0.1 2010-03-05
68
+ * Copy all needed config files when sunspot-installer run with force option
69
+
70
+ == 1.0.0 2010-03-03
71
+ * Multiselect Field Faceting
72
+ * Named field facets
73
+ * Upgrade to Solr 1.4
74
+ * Deletion by query
75
+ * Allow :latitude and :longitude as coordinate method names
76
+ * Assumed inconsistency
77
+ * Support for TrieField numeric/time types
78
+ * Built-in Session Proxies: Thread-local, master/slave, sharding
79
+ * Give DSL blocks access to calling context
80
+ * Create sunspot-installer executable, which modifies an existing
81
+ schema/solrconfig to work with Sunspot
82
+ * Support for Long and Double types
83
+ * new_search method accepts DSL block
84
+ * Sunspot::Server now a real class that manages embedded Sunspot instance
85
+ * Add Search#each_hit_with_result method
86
+ * Able to access stored dynamic fields
87
+ * Access dynamic facets using the #facet method
88
+ * Remove accidental existence of dynamic_text fields
89
+ * Upgrade to RSolr 0.12.1
90
+ * Switch from LocalSolr to solr-spatial-light
91
+ * Turn off request logging in Jetty for default Solr install
92
+ * Full support for class-reloading of Sunspot-setup classes
93
+ * Support time ranges outside of 32-bit range
94
+ * Remove sunspot-configure-solr executable
95
+ * new_search method accepts DSL block
96
+
97
+ == 0.10.8 2009-11-24
98
+ * Strictly enforce RSolr 0.9.6 gem dependency (newer ones broken)
99
+
100
+ == 0.10.7 2009-11-16
101
+ * Ignore boost_fields that don't apply
102
+ * Ability to specify text_fields inside connectives
103
+ * Fix bug with newlines in strings incorrectly being considered multi-value
104
+ * Compatibility with RSolr 0.10.1
105
+ * Remove commented-out code entirely
106
+
107
+ == 0.10.6 2009-11-05
108
+ * Support more dismax parameters
109
+ * Support multiple boost queries
110
+ * Allow "extra" facet rows
111
+ * Allow exclusion of fulltext fields
112
+ * Allow specification of per-field highlighting params
113
+ * Specify coordinates using block extraction
114
+ * Return empty array if no highlights available
115
+ * Get stored text fields from hits
116
+ * Update docs to reflect a requirement of at least one search type
117
+ * added --max-memory and --min-memory parameters to sunspot-solr
118
+ * LocalLucene and LocalSolr compatible with Java 1.5
119
+
120
+ == 0.10.5 2009-10-22
121
+ * Fix highlighting for multiple-model search
122
+
123
+ == 0.10.4 2009-10-20
124
+ * Add adjust_params method, allowing experts to manually edit Solr params
125
+ * Track adds and deletes separately in session, and expose delete_dirty? method
126
+ * Allow clients to inject a singleton session proxy
127
+
128
+ == 0.10.3 2009-10-15
129
+ * Contiguous, not continuous
130
+ * Fail fast if less-than-1 radius passed for local search
131
+
132
+ == 0.10.2 2009-10-09
133
+ * Add Sunspot.config.xml_builder option, which is passed to RSolr
134
+
135
+ == 0.10.1 2009-10-08
136
+ * Fix directory bugs in sunspot-solr executable
137
+
138
+ == 0.10.0 2009-10-08
139
+ * Support for geographical search using LocalSolr
140
+ * Support for keyword highlighting, with custom deferred formatting
141
+ * New fulltext DSL for specifying advanced dismax options
142
+ * Support boost queries
143
+ * Support for search-time field boost
144
+ * Support for phrase fields
145
+ * Support for prefix queries
146
+ * Set default search-time field boost in setup
147
+ * Restrict field facet to a set of desired values
148
+ * Query facets support all facet options
149
+ * Allow scoping by text fields
150
+ * Support executing searches repeatedly
151
+ * Allow setting of Solr URL for integration tests in environment variable
152
+ * Add support for master/slave configurations
153
+ * Added logging options to sunspot-solr executable
154
+ * Added default solr config file location to Sunspot::Configuration
155
+ * Informative, non-firehose Search#inspect
156
+ * No longer require arguments to #paginate
157
+ * Silently ignore keyword calls with nil/blank/whitespace keywords
158
+ * Don't require that all searched types have a referenced field
159
+ * Correct backwards ranges
160
+ * Raise descriptive error if no types passed to search
161
+ * Handle empty query facets, query facet rows, and connectives
162
+ * Quote values in range restrictions if they contain spaces
163
+ * Fix bug in Sunspot::Util.full_const_get
164
+ * Remove support for :other option in time faceting
165
+ * Remove order_by_random() method
166
+ * Removed options and Query from public API
167
+ * Use built-in optparse instead of optiflag in bin/sunspot-solr
168
+ * Remove dependency on haml and use erb since it is only used to generate one file
169
+
170
+ == 0.9.0 2009-07-21
171
+ * Use Dismax parser for keyword search
172
+ * Field and document boosting
173
+ * Specify which fields to search in keyword search
174
+ * Allow indexing of multiple values in text fields
175
+ * Access keyword relevance score in Hit objects
176
+ * Allow stored fields, retrieve stored values from Hit objects
177
+ * Support more values in shorthand restrictions
178
+ * Disjunctions and conjunctions
179
+ * Random ordering
180
+ * Control all options for field facets
181
+ * Time range facets
182
+ * Get referenced objects from facets on foreign keys
183
+ * Facet by class
184
+ * Batch indexing
185
+ * New Date field type
186
+ * Direct access to data accessors
187
+ * Executable to configure production Solr instances
188
+ * Replace solr-ruby with RSolr
189
+ * Remove accidental ActiveSupport dependency
190
+
191
+ == 0.8.9 2009-06-23
192
+ * Fix OrderedHash bug in older versions of ActiveSupport
193
+
194
+ == 0.8.8 2009-06-15
195
+ * Escape type names to support namespaced classes
196
+ * Fix bug with anonymous modules in Ruby 1.9
197
+
198
+ == 0.8.7 2009-06-10
199
+ * Add --pid-dir option for sunspot-solr executable
200
+
201
+ == 0.8.5 2009-06-09
202
+ * Added dependencies for sunspot-solr executable to gem dependencies
203
+ * Search for adapters using class ancestors rather than superclasses
204
+
205
+ == 0.8.3 2009-06-03
206
+ * Index objects passed as a collection in a single HTTP request
207
+
208
+ == 0.8.2 2009-05-27
209
+ * Allow specification of Solr home when using sunspot-solr
210
+
211
+ == 0.8.1 2009-05-26
212
+ * Add Search#execute! to public API
213
+
214
+ == 0.8.0 2009-05-22
215
+ * Access query API directly; instantiate search without running it
216
+ * Dynamic fields
217
+ * Search blocks can be evaluated in calling context
218
+
219
+ == 0.7.3 2009-05-06
220
+ * Better exception handling when class doesn't have adapter/setup
221
+
222
+ == 0.7.2 2009-04-29
223
+ * Dirty sessions
224
+
225
+ == 0.7.1 2009-04-29
226
+ * Removed extlib dependency from gemspec
227
+
228
+ == 0.7.0 2009-04-28
229
+ * Less magic in the DSL
230
+ * Restrict by empty values
231
+ * Negative scoping using without() method
232
+ * Exclusion by object identity using without(instance)
233
+ * Support for faceting
234
+ * Explicit commits
235
+ * Boolean field type
236
+ * Attribute field flexibility
237
+ * Virtual field blocks can be evaluated in calling context
238
+ * Order available by multiple fields
239
+ * New adapter API
240
+ * Got rid of builder API
241
+ * Full documentation
242
+
243
+ == 0.0.2 2009-02-14
244
+ * Run sunspot's built-in Solr instance using
245
+ sunspot-solr executable
246
+ * Search hash interpretation delegated to
247
+ Builder object
248
+
249
+ == 0.0.1 2008-12-11
250
+ * Initial release
251
+ * Define indexing for any class using DSL
252
+ * Search indexed classes using DSL
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Permission is hereby granted, free of charge, to any person obtaining
2
+ a copy of this software and associated documentation files (the
3
+ 'Software'), to deal in the Software without restriction, including
4
+ without limitation the rights to use, copy, modify, merge, publish,
5
+ distribute, sublicense, and/or sell copies of the Software, and to
6
+ permit persons to whom the Software is furnished to do so, subject to
7
+ the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be
10
+ included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
13
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
15
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
16
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
17
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ Dir['tasks/**/*.rake'].each { |t| load t }
6
+
7
+ desc "Run all examples"
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.rspec_opts = '--format documentation'
10
+ t.ruby_opts = "-W1"
11
+ end
12
+
13
+ task :default => :spec
data/TODO ADDED
@@ -0,0 +1,13 @@
1
+ === Sunspot 1.1.x ===
2
+ * commitWithin (needs support from RSolr, currently available in master)
3
+ * commit options (non-blocking, etc.)
4
+
5
+ === Someday ===
6
+ * Shorthand arguments to Sunspot#search
7
+ * Rudimentary fulltext prefixing support
8
+
9
+ === Solr 1.5 ===
10
+ * Field Collapsing (SOLR-236)
11
+ * Support for official spatial support (SOLR-773)
12
+ * Support sorting by function
13
+ * Support string constants in functions
@@ -0,0 +1,40 @@
1
+ module LightConfig
2
+ class Configuration
3
+ def initialize(&block)
4
+ @properties = {}
5
+ ::LightConfig::Builder.new(self).instance_eval(&block)
6
+ singleton = (class <<self; self; end)
7
+ @properties.keys.each do |property|
8
+ singleton.module_eval do
9
+ define_method property do
10
+ @properties[property]
11
+ end
12
+
13
+ define_method "#{property}=" do |value|
14
+ @properties[property] = value
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ class Builder
22
+ def initialize(configuration)
23
+ @configuration = configuration
24
+ end
25
+
26
+ def method_missing(method, *args, &block)
27
+ raise ArgumentError("wrong number of arguments(#{args.length} for 1)") unless args.length < 2
28
+ value = if block then ::LightConfig::Configuration.new(&block)
29
+ else args.first
30
+ end
31
+ @configuration.instance_variable_get(:@properties)[method] = value
32
+ end
33
+ end
34
+
35
+ class <<self
36
+ def build(&block)
37
+ LightConfig::Configuration.new(&block)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,265 @@
1
+ module Sunspot
2
+ #
3
+ # Sunspot works by saving references to the primary key (or natural ID) of
4
+ # each indexed object, and then retrieving the objects from persistent storage
5
+ # when their IDs are referenced in search results. In order for Sunspot to
6
+ # know what an object's primary key is, and how to retrieve objects from
7
+ # persistent storage given a primary key, an adapter must be registered for
8
+ # that object's class or one of its superclasses (for instance, an adapter
9
+ # registered for ActiveRecord::Base would be used for all ActiveRecord
10
+ # models).
11
+ #
12
+ # To provide Sunspot with this ability, adapters must have two roles:
13
+ #
14
+ # Data accessor::
15
+ # A subclass of Sunspot::Adapters::DataAccessor, this object is instantiated
16
+ # with a particular class and must respond to the #load() method, which
17
+ # returns an object from persistent storage given that object's primary key.
18
+ # It can also optionally implement the #load_all() method, which returns
19
+ # a collection of objects given a collection of primary keys, if that can be
20
+ # done more efficiently than calling #load() on each key.
21
+ # Instance adapter::
22
+ # A subclass of Sunspot::Adapters::InstanceAdapter, this object is
23
+ # instantiated with a particular instance. Its only job is to tell Sunspot
24
+ # what the object's primary key is, by implementing the #id() method.
25
+ #
26
+ # Adapters are registered by registering their two components, telling Sunspot
27
+ # that they are available for one or more classes, and all of their
28
+ # subclasses. See Sunspot::Adapters::DataAccessor.register and
29
+ # Sunspot::Adapters::InstanceAdapter.register for the details.
30
+ #
31
+ # See spec/mocks/mock_adapter.rb for an example of how adapter classes should
32
+ # be implemented.
33
+ #
34
+ module Adapters
35
+ # Subclasses of the InstanceAdapter class should implement the #id method,
36
+ # which returns the primary key of the instance stored in the @instance
37
+ # variable. The primary key must be unique within the scope of the
38
+ # instance's class.
39
+ #
40
+ # ==== Example:
41
+ #
42
+ # class FileAdapter < Sunspot::Adapters::InstanceAdapter
43
+ # def id
44
+ # File.expand_path(@instance.path)
45
+ # end
46
+ # end
47
+ #
48
+ # # then in your initializer
49
+ # Sunspot::Adapters::InstanceAdapter.register(MyAdapter, File)
50
+ #
51
+ class InstanceAdapter
52
+ def initialize(instance) #:nodoc:
53
+ @instance = instance
54
+ end
55
+
56
+ #
57
+ # The universally-unique ID for this instance that will be stored in solr
58
+ #
59
+ # ==== Returns
60
+ #
61
+ # String:: ID for use in Solr
62
+ #
63
+ def index_id #:nodoc:
64
+ InstanceAdapter.index_id_for(@instance.class.name, id)
65
+ end
66
+
67
+ class <<self
68
+ # Instantiate an InstanceAdapter for the given object, searching for
69
+ # registered adapters for the object's class.
70
+ #
71
+ # ==== Parameters
72
+ #
73
+ # instance<Object>:: The instance to adapt
74
+ #
75
+ # ==== Returns
76
+ #
77
+ # InstanceAdapter::
78
+ # An instance of an InstanceAdapter implementation that
79
+ # wraps the given instance
80
+ #
81
+ def adapt(instance) #:nodoc:
82
+ self.for(instance.class).new(instance)
83
+ end
84
+
85
+ # Register an instance adapter for a set of classes. When searching for
86
+ # an adapter for a given instance, Sunspot starts with the instance's
87
+ # class, and then searches for registered adapters up the class's
88
+ # ancestor chain.
89
+ #
90
+ # ==== Parameters
91
+ #
92
+ # instance_adapter<Class>:: The instance adapter class to register
93
+ # classes...<Class>::
94
+ # One or more classes that this instance adapter adapts
95
+ #
96
+ def register(instance_adapter, *classes)
97
+ classes.each do |clazz|
98
+ instance_adapters[clazz.name.to_sym] = instance_adapter
99
+ end
100
+ end
101
+
102
+ # Find the best InstanceAdapter implementation that adapts the given
103
+ # class. Starting with the class and then moving up the ancestor chain,
104
+ # looks for registered InstanceAdapter implementations.
105
+ #
106
+ # ==== Parameters
107
+ #
108
+ # clazz<Class>:: The class to find an InstanceAdapter for
109
+ #
110
+ # ==== Returns
111
+ #
112
+ # Class:: Subclass of InstanceAdapter, or nil if none found
113
+ #
114
+ # ==== Raises
115
+ #
116
+ # Sunspot::NoAdapterError:: If no adapter is registered for this class
117
+ #
118
+ def for(clazz) #:nodoc:
119
+ original_class_name = clazz.name
120
+ clazz.ancestors.each do |ancestor_class|
121
+ next if ancestor_class.name.nil? || ancestor_class.name.empty?
122
+ class_name = ancestor_class.name.to_sym
123
+ return instance_adapters[class_name] if instance_adapters[class_name]
124
+ end
125
+
126
+ raise(Sunspot::NoAdapterError,
127
+ "No adapter is configured for #{original_class_name} or its superclasses. See the documentation for Sunspot::Adapters")
128
+ end
129
+
130
+ def index_id_for(class_name, id) #:nodoc:
131
+ "#{class_name} #{id}"
132
+ end
133
+
134
+ protected
135
+
136
+ # Lazy-initialize the hash of registered instance adapters
137
+ #
138
+ # ==== Returns
139
+ #
140
+ # Hash:: Hash containing class names keyed to instance adapter classes
141
+ #
142
+ def instance_adapters #:nodoc:
143
+ @instance_adapters ||= {}
144
+ end
145
+ end
146
+ end
147
+
148
+ # Subclasses of the DataAccessor class take care of retreiving instances of
149
+ # the adapted class from (usually persistent) storage. Subclasses must
150
+ # implement the #load method, which takes an id (the value returned by
151
+ # InstanceAdapter#id, as a string), and returns the instance referenced by
152
+ # that ID. Optionally, it can also override the #load_all method, which
153
+ # takes an array of IDs and returns an array of instances in the order
154
+ # given. #load_all need only be implemented if it can be done more
155
+ # efficiently than simply iterating over the IDs and calling #load on each
156
+ # individually.
157
+ #
158
+ # ==== Example
159
+ #
160
+ # class FileAccessor < Sunspot::Adapters::InstanceAdapter
161
+ # def load(id)
162
+ # @clazz.open(id)
163
+ # end
164
+ # end
165
+ #
166
+ # Sunspot::Adapters::DataAccessor.register(FileAccessor, File)
167
+ #
168
+ class DataAccessor
169
+ def initialize(clazz) #:nodoc:
170
+ @clazz = clazz
171
+ end
172
+
173
+ # Subclasses can override this class to provide more efficient bulk
174
+ # loading of instances. Instances must be returned in the same order
175
+ # that the IDs were given.
176
+ #
177
+ # ==== Parameters
178
+ #
179
+ # ids<Array>:: collection of IDs
180
+ #
181
+ # ==== Returns
182
+ #
183
+ # Array:: collection of instances, in order of IDs given
184
+ #
185
+ def load_all(ids)
186
+ ids.map { |id| self.load(id) }
187
+ end
188
+
189
+ class <<self
190
+ # Create a DataAccessor for the given class, searching registered
191
+ # adapters for the best match. See InstanceAdapter#adapt for discussion
192
+ # of inheritence.
193
+ #
194
+ # ==== Parameters
195
+ #
196
+ # clazz<Class>:: Class to create DataAccessor for
197
+ #
198
+ # ==== Returns
199
+ #
200
+ # DataAccessor::
201
+ # DataAccessor implementation which provides access to given class
202
+ #
203
+ def create(clazz) #:nodoc:
204
+ self.for(clazz).new(clazz)
205
+ end
206
+
207
+ # Register data accessor for a set of classes. When searching for
208
+ # an accessor for a given class, Sunspot starts with the class,
209
+ # and then searches for registered adapters up the class's ancestor
210
+ # chain.
211
+ #
212
+ # ==== Parameters
213
+ #
214
+ # data_accessor<Class>:: The data accessor class to register
215
+ # classes...<Class>::
216
+ # One or more classes that this data accessor providess access to
217
+ #
218
+ def register(data_accessor, *classes)
219
+ classes.each do |clazz|
220
+ data_accessors[clazz.name.to_sym] = data_accessor
221
+ end
222
+ end
223
+
224
+ # Find the best DataAccessor implementation that adapts the given class.
225
+ # Starting with the class and then moving up the ancestor chain, looks
226
+ # for registered DataAccessor implementations.
227
+ #
228
+ # ==== Parameters
229
+ #
230
+ # clazz<Class>:: The class to find a DataAccessor for
231
+ #
232
+ # ==== Returns
233
+ #
234
+ # Class:: Implementation of DataAccessor
235
+ #
236
+ # ==== Raises
237
+ #
238
+ # Sunspot::NoAdapterError:: If no data accessor exists for the given class
239
+ #
240
+ def for(clazz) #:nodoc:
241
+ original_class_name = clazz.name
242
+ clazz.ancestors.each do |ancestor_class|
243
+ next if ancestor_class.name.nil? || ancestor_class.name.empty?
244
+ class_name = ancestor_class.name.to_sym
245
+ return data_accessors[class_name] if data_accessors[class_name]
246
+ end
247
+ raise(Sunspot::NoAdapterError,
248
+ "No data accessor is configured for #{original_class_name} or its superclasses. See the documentation for Sunspot::Adapters")
249
+ end
250
+
251
+ protected
252
+
253
+ # Lazy-initialize the hash of registered data accessors
254
+ #
255
+ # ==== Returns
256
+ #
257
+ # Hash:: Hash containing class names keyed to data accessor classes
258
+ #
259
+ def data_accessors #:nodoc:
260
+ @adapters ||= {}
261
+ end
262
+ end
263
+ end
264
+ end
265
+ end
@@ -0,0 +1,62 @@
1
+ module Sunspot
2
+ #
3
+ # Keeps a stack of batches and helps out when Indexer is asked to batch documents.
4
+ #
5
+ # If the client does something like
6
+ #
7
+ # Sunspot.batch do
8
+ # some_code_here
9
+ # which_triggers_some_other_code
10
+ # which_again_calls
11
+ # Sunspot.batch { ... }
12
+ # end
13
+ #
14
+ # it is the Batcher's job to keep track of these nestings. The inner will
15
+ # be sent of to be indexed first.
16
+ #
17
+ class Batcher
18
+ include Enumerable
19
+
20
+ # Raised if you ask to end current, but no current exists
21
+ class NoCurrentBatchError < StandardError; end
22
+
23
+ def initialize
24
+ @stack = []
25
+ end
26
+
27
+ def current
28
+ @stack.last or start_new
29
+ end
30
+
31
+ def start_new
32
+ (@stack << []).last
33
+ end
34
+
35
+ def end_current
36
+ fail NoCurrentBatchError if @stack.empty?
37
+
38
+ @stack.pop
39
+ end
40
+
41
+ def depth
42
+ @stack.length
43
+ end
44
+
45
+ def batching?
46
+ depth > 0
47
+ end
48
+
49
+ def each(&block)
50
+ current.each(&block)
51
+ end
52
+
53
+ def push(value)
54
+ current << value
55
+ end
56
+ alias << push
57
+
58
+ def concat(values)
59
+ current.concat values
60
+ end
61
+ end
62
+ end