sunspot_rails 1.2.1 → 1.3.0.rc6
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.
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/History.txt +15 -0
- data/README.rdoc +14 -7
- data/Rakefile +0 -6
- data/TESTING.md +32 -18
- data/dev_tasks/spec.rake +103 -18
- data/gemfiles/rails-2.3.14 +15 -0
- data/gemfiles/rails-3.0.10 +15 -0
- data/gemfiles/rails-3.1.1 +15 -0
- data/lib/sunspot/rails.rb +13 -6
- data/lib/sunspot/rails/configuration.rb +25 -4
- data/lib/sunspot/rails/log_subscriber.rb +33 -0
- data/lib/sunspot/rails/railtie.rb +10 -0
- data/lib/sunspot/rails/railties/controller_runtime.rb +36 -0
- data/lib/sunspot/rails/searchable.rb +88 -20
- data/lib/sunspot/rails/server.rb +10 -77
- data/lib/sunspot/rails/solr_instrumentation.rb +20 -0
- data/lib/sunspot/rails/solr_logging.rb +16 -17
- data/lib/sunspot/rails/stub_session_proxy.rb +56 -2
- data/lib/sunspot/rails/tasks.rb +56 -33
- data/lib/sunspot_rails.rb +5 -0
- data/spec/configuration_spec.rb +27 -5
- data/spec/model_lifecycle_spec.rb +1 -1
- data/spec/model_spec.rb +240 -1
- data/spec/rails_template/app/controllers/application_controller.rb +10 -0
- data/spec/rails_template/app/controllers/posts_controller.rb +6 -0
- data/spec/rails_template/app/models/author.rb +8 -0
- data/spec/rails_template/app/models/blog.rb +12 -0
- data/spec/rails_template/app/models/location.rb +2 -0
- data/spec/rails_template/app/models/photo_post.rb +2 -0
- data/spec/rails_template/app/models/post.rb +11 -0
- data/spec/rails_template/app/models/post_with_auto.rb +10 -0
- data/spec/rails_template/app/models/post_with_default_scope.rb +11 -0
- data/spec/rails_template/config/boot.rb +127 -0
- data/spec/rails_template/config/preinitializer.rb +22 -0
- data/spec/rails_template/config/routes.rb +9 -0
- data/spec/rails_template/config/sunspot.yml +22 -0
- data/spec/rails_template/db/schema.rb +27 -0
- data/spec/request_lifecycle_spec.rb +1 -1
- data/spec/searchable_spec.rb +12 -0
- data/spec/server_spec.rb +2 -6
- data/spec/session_spec.rb +35 -2
- data/spec/shared_examples/indexed_after_save.rb +8 -0
- data/spec/shared_examples/not_indexed_after_save.rb +8 -0
- data/spec/spec_helper.rb +4 -2
- data/spec/stub_session_proxy_spec.rb +2 -2
- data/sunspot_rails.gemspec +43 -0
- metadata +114 -44
- data/lib/sunspot/rails/version.rb +0 -5
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/History.txt
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
== 1.3.0
|
2
|
+
* `Model.index` correctly uses `:first_id` option (Hamza Khan-Cheema)
|
3
|
+
* Solr request performance is instrumented in Rails (Paco Guzmán)
|
4
|
+
* Reindexing tasks display a progress bar if `progress_bar` gem is available (Paul Carey)
|
5
|
+
* Deprecated Rails syntax is removed from `Sunspot::Rails::Searchable` (Steve Schwartz)
|
6
|
+
* Deprecated syntax is removed from rake tasks (Huned Botee)
|
7
|
+
* `sunspot:reindex` rake task correctly handles namespaced models (João Gradim)
|
8
|
+
* `bind_address` parameter can be specified in `sunspot.yml` to bind Solr to a
|
9
|
+
specific interface (Sylvain Utard)
|
10
|
+
* `disabled` parameter can be specified in `sunspot.yml` to stub out the
|
11
|
+
connection to Solr (David B)
|
12
|
+
|
13
|
+
== 1.2.1 2010-12-28
|
14
|
+
* Decreased default reindexing batch size from 500 to 50
|
15
|
+
|
1
16
|
== 1.2.0 2010-12-28
|
2
17
|
* Compatible with both Rails 2 and Rails 3
|
3
18
|
* Configure Sunspot with a SOLR_URL or WEBSOLR_URL environment variable, also
|
data/README.rdoc
CHANGED
@@ -21,6 +21,10 @@ Sunspot::Rails has been tested with Rails versions 2.3 and 3.0
|
|
21
21
|
In your <code>Gemfile</code>:
|
22
22
|
|
23
23
|
gem 'sunspot_rails'
|
24
|
+
# This is an optional packaged Solr:
|
25
|
+
group :test, :development do
|
26
|
+
gem 'sunspot_solr'
|
27
|
+
end
|
24
28
|
|
25
29
|
== Installation in Rails 2
|
26
30
|
|
@@ -28,7 +32,12 @@ In your project's <code>config/environment.rb</code>, add the following gem depe
|
|
28
32
|
|
29
33
|
config.gem 'sunspot'
|
30
34
|
config.gem 'sunspot_rails'
|
31
|
-
|
35
|
+
|
36
|
+
And in your project's <code>config/development.rb</code> and <code>config/test.rb</code>,
|
37
|
+
add the following gem dependency to install the optional packaged Solr:
|
38
|
+
|
39
|
+
config.gem 'sunspot_solr'
|
40
|
+
|
32
41
|
Install the gems with:
|
33
42
|
|
34
43
|
rake gems:install
|
@@ -53,7 +62,8 @@ Sunspot::Rails will detect them and tell Solr to use your local configurations.
|
|
53
62
|
Use caution when modifying <code>schema.xml</code> - Sunspot relies on the
|
54
63
|
field naming scheme in the packaged schema file.
|
55
64
|
|
56
|
-
To start up a Solr instance, issue the following
|
65
|
+
To start up a Solr instance, issue the following (requires sunspot_solr to be
|
66
|
+
installed):
|
57
67
|
|
58
68
|
rake sunspot:solr:start
|
59
69
|
|
@@ -148,7 +158,6 @@ without actually loading the models out of the database. For that, you can
|
|
148
158
|
call +search_ids+, using the same block format as #search. This will return an
|
149
159
|
array of IDs.
|
150
160
|
|
151
|
-
|
152
161
|
=== Searching for multiple types
|
153
162
|
|
154
163
|
Sunspot is entirely agnostic about whether searches are for one or more types;
|
@@ -205,7 +214,6 @@ remove those documents from the index, use +clean_index_orphans+. Note that
|
|
205
214
|
neither of these operations should be needed if Sunspot and Sunspot::Rails are
|
206
215
|
used as intended.
|
207
216
|
|
208
|
-
|
209
217
|
== Testing Solr integration using RSpec
|
210
218
|
|
211
219
|
To disable the sunspot-solr integration for your active record models, require
|
@@ -217,7 +225,7 @@ Then, in your spec, use the #disconnect_sunspot method:
|
|
217
225
|
|
218
226
|
describe Post do
|
219
227
|
disconnect_sunspot
|
220
|
-
|
228
|
+
|
221
229
|
it 'should have some behavior'
|
222
230
|
# ...
|
223
231
|
end
|
@@ -238,8 +246,7 @@ Posts about Sunspot on my blog are available at http://outofti.me/tagged/sunspot
|
|
238
246
|
|
239
247
|
== Bugs
|
240
248
|
|
241
|
-
Please submit bug reports to
|
242
|
-
http://outoftime.lighthouseapp.com/projects/20339-sunspot
|
249
|
+
Please submit bug reports to https://github.com/sunspot/sunspot/issues
|
243
250
|
|
244
251
|
== Contributors
|
245
252
|
|
data/Rakefile
CHANGED
@@ -7,12 +7,6 @@ if File.exist?(sunspot_lib = File.expand_path(File.join(File.dirname(__FILE__),
|
|
7
7
|
end
|
8
8
|
|
9
9
|
task :environment do
|
10
|
-
if ENV['SUNSPOT_LIB']
|
11
|
-
$: << ENV['SUNSPOT_LIB']
|
12
|
-
end
|
13
|
-
ENV['RAILS_ROOT'] ||= File.join(File.dirname(__FILE__), 'spec', 'rails3')
|
14
|
-
ENV['RAILS_ENV'] ||= 'test'
|
15
|
-
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config', 'environment.rb'))
|
16
10
|
end
|
17
11
|
|
18
12
|
FileList['dev_tasks/*.rake', 'lib/sunspot/rails/tasks.rb'].each { |file| load(file) }
|
data/TESTING.md
CHANGED
@@ -1,35 +1,49 @@
|
|
1
1
|
# Testing `sunspot_rails`
|
2
2
|
|
3
|
-
|
3
|
+
All the paths mentioned in here are relative to the current directory,
|
4
|
+
or `sunspot/sunspot_rails`.
|
4
5
|
|
5
|
-
The `sunspot_rails` gem is tested with RSpec, and its spec suite is
|
6
|
+
The `sunspot_rails` gem is tested with RSpec, and its spec suite is
|
7
|
+
located in `spec`.
|
6
8
|
|
7
|
-
|
9
|
+
The specs are run against Rails 2 and Rails 3 applications which are
|
10
|
+
dynamically generated in `tmp/`
|
11
|
+
|
12
|
+
**NOTE:** Because the applications are dynamically generated, the specs
|
13
|
+
must be run with the rake task (described below) and not simply with
|
14
|
+
`rspec spec`.
|
8
15
|
|
9
16
|
## Start Solr
|
10
17
|
|
11
18
|
Specs expect to connect to Solr on `http://localhost:8980/solr`
|
12
19
|
|
13
|
-
|
20
|
+
sunspot-solr start -p 8980
|
21
|
+
|
22
|
+
## Invoke specs
|
14
23
|
|
15
|
-
|
24
|
+
To run the specs against every Rails version defined in
|
25
|
+
`gemfiles/rails-*`:
|
16
26
|
|
17
|
-
|
27
|
+
rake spec
|
18
28
|
|
19
|
-
|
20
|
-
bundle install
|
21
|
-
cd ../rails3
|
22
|
-
bundle install
|
23
|
-
popd
|
29
|
+
### Focused on specific versions
|
24
30
|
|
25
|
-
|
31
|
+
To run the specs against a specific version or versions of Rails:
|
32
|
+
|
33
|
+
rake spec VERSIONS=2.3.14
|
34
|
+
rake spec VERSIONS=2.3.14,3.0.10
|
35
|
+
|
36
|
+
To make a Rails the default for your shell session, export the
|
37
|
+
environment variable:
|
38
|
+
|
39
|
+
export VERSIONS=2.3.14
|
26
40
|
|
27
|
-
|
28
|
-
|
41
|
+
Though be sure to run the tests against all versions before submitting
|
42
|
+
code!
|
29
43
|
|
30
|
-
|
31
|
-
rake spec:rails3
|
44
|
+
### Focused on specific specs
|
32
45
|
|
33
|
-
|
46
|
+
To run a specific spec or spec file:
|
34
47
|
|
35
|
-
|
48
|
+
rake spec SPEC=spec/model_spec.rb
|
49
|
+
rake spec SPEC=spec/model_spec.rb:4 # run spec(s) that start on line 4
|
data/dev_tasks/spec.rake
CHANGED
@@ -1,22 +1,107 @@
|
|
1
|
-
|
2
|
-
task :spec => [:"spec:rails2", :"spec:rails3"]
|
1
|
+
require 'fileutils'
|
3
2
|
|
4
3
|
namespace :spec do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
4
|
+
def rails_app_path(version)
|
5
|
+
File.join(File.dirname(__FILE__), "..", "tmp", "rails_#{version.gsub(".", "_")}_app")
|
6
|
+
end
|
7
|
+
|
8
|
+
def gemfile_path(version)
|
9
|
+
File.join(File.dirname(__FILE__), "..", "gemfiles", "rails-#{version}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def vendor_path(version)
|
13
|
+
File.expand_path("vendor/bundle", rails_app_path(version))
|
14
|
+
end
|
15
|
+
|
16
|
+
def rails_template_path
|
17
|
+
File.join(File.dirname(__FILE__), "..", "spec", "rails_template")
|
18
|
+
end
|
19
|
+
|
20
|
+
task :run_with_rails => [:set_gemfile, :generate_rails_app, :setup_rails_app, :run]
|
21
|
+
|
22
|
+
task :set_gemfile do
|
23
|
+
version = ENV['VERSION']
|
24
|
+
|
25
|
+
ENV['BUNDLE_PATH'] = vendor_path(version)
|
26
|
+
ENV['BUNDLE_GEMFILE'] = gemfile_path(version)
|
27
|
+
|
28
|
+
unless File.exist?(ENV['BUNDLE_PATH'])
|
29
|
+
puts "Installing gems for Rails #{version} (this will only be done once)..."
|
30
|
+
`bundle install #{ENV['BUNDLE_ARGS']}`
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
task :generate_rails_app do
|
35
|
+
version = ENV['VERSION']
|
36
|
+
app_path = rails_app_path(version)
|
37
|
+
|
38
|
+
unless File.exist?(File.expand_path("config/environment.rb", app_path))
|
39
|
+
rails_cmd = "bundle exec rails _#{version}_"
|
40
|
+
|
41
|
+
puts "Generating Rails #{version} application..."
|
42
|
+
if version.start_with?("2")
|
43
|
+
`#{rails_cmd} \"#{app_path}\" --force`
|
44
|
+
elsif version.start_with?("3")
|
45
|
+
`#{rails_cmd} new \"#{app_path}\" --force --skip-git --skip-javascript --skip-gemfile --skip-sprockets`
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
task :setup_rails_app do
|
51
|
+
version = ENV['VERSION']
|
52
|
+
app_path = rails_app_path(version)
|
53
|
+
|
54
|
+
FileUtils.cp_r File.join(rails_template_path, "."), app_path
|
55
|
+
end
|
56
|
+
|
57
|
+
task :run do
|
58
|
+
version = ENV['VERSION']
|
59
|
+
|
60
|
+
ENV['BUNDLE_GEMFILE'] = gemfile_path(version)
|
61
|
+
ENV['RAILS_ROOT'] = rails_app_path(version)
|
62
|
+
|
63
|
+
spec_command = if version.start_with?("2")
|
64
|
+
"spec"
|
65
|
+
elsif version.start_with?("3")
|
66
|
+
"rspec"
|
67
|
+
end
|
68
|
+
|
69
|
+
system "bundle exec #{spec_command} #{ENV['SPEC'] || 'spec/*_spec.rb'} --color"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def rails_all_versions
|
74
|
+
versions = []
|
75
|
+
Dir.glob(File.join(File.dirname(__FILE__), "..", "gemfiles", "rails-*")).each do |gemfile|
|
76
|
+
if !gemfile.end_with?(".lock") && gemfile =~ /rails-([0-9.]+)/
|
77
|
+
versions << $1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
versions
|
82
|
+
end
|
83
|
+
|
84
|
+
def reenable_spec_tasks
|
85
|
+
Rake::Task.tasks.each do |task|
|
86
|
+
if task.name =~ /spec:/
|
87
|
+
task.reenable
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
desc 'Run spec suite in all Rails versions'
|
93
|
+
task :spec do
|
94
|
+
versions = if ENV['RAILS']
|
95
|
+
ENV['RAILS'].split(",")
|
96
|
+
else
|
97
|
+
rails_all_versions
|
98
|
+
end
|
99
|
+
|
100
|
+
versions.each do |version|
|
101
|
+
puts "Running specs against Rails #{version}..."
|
102
|
+
|
103
|
+
ENV['VERSION'] = version
|
104
|
+
reenable_spec_tasks
|
105
|
+
Rake::Task['spec:run_with_rails'].invoke
|
21
106
|
end
|
22
107
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'rails', '2.3.14'
|
4
|
+
gem 'sqlite3-ruby', '~> 1.3.1'
|
5
|
+
|
6
|
+
gem 'sunspot', :path => File.expand_path('../../../sunspot', __FILE__)
|
7
|
+
gem 'sunspot_solr', :path => File.expand_path('../../../sunspot_solr', __FILE__)
|
8
|
+
gem 'sunspot_rails', :path => File.expand_path('../..', __FILE__)
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'rspec-rails', '~> 1.3.4'
|
12
|
+
gem 'ruby-debug19', :require => nil, :platforms => :mri_19
|
13
|
+
gem 'test-unit', '1.2.3', :platforms => :mri_19
|
14
|
+
gem 'ruby-debug', :require => nil, :platforms => :mri_18
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'rails', '3.0.10'
|
4
|
+
gem 'sqlite3-ruby', '~> 1.3.1'
|
5
|
+
|
6
|
+
gem 'sunspot', :path => File.expand_path('../../../sunspot', __FILE__)
|
7
|
+
gem 'sunspot_solr', :path => File.expand_path('../../../sunspot_solr', __FILE__)
|
8
|
+
gem 'sunspot_rails', :path => File.expand_path('../..', __FILE__)
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'rspec-rails', '~> 2.0.0'
|
12
|
+
gem 'ruby-debug19', :require => nil, :platforms => :mri_19
|
13
|
+
gem 'test-unit', '1.2.3', :platforms => :mri_19
|
14
|
+
gem 'ruby-debug', :require => nil, :platforms => :mri_18
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'rails', '3.1.1'
|
4
|
+
gem 'sqlite3-ruby', '~> 1.3.1'
|
5
|
+
|
6
|
+
gem 'sunspot', :path => File.expand_path('../../../sunspot', __FILE__)
|
7
|
+
gem 'sunspot_solr', :path => File.expand_path('../../../sunspot_solr', __FILE__)
|
8
|
+
gem 'sunspot_rails', :path => File.expand_path('../..', __FILE__)
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'rspec-rails', '~> 2.0.0'
|
12
|
+
gem 'ruby-debug19', :require => nil, :platforms => :mri_19
|
13
|
+
gem 'test-unit', '1.2.3', :platforms => :mri_19
|
14
|
+
gem 'ruby-debug', :require => nil, :platforms => :mri_18
|
15
|
+
end
|
data/lib/sunspot/rails.rb
CHANGED
@@ -6,9 +6,14 @@ require File.join(File.dirname(__FILE__), 'rails', 'searchable')
|
|
6
6
|
|
7
7
|
module Sunspot #:nodoc:
|
8
8
|
module Rails #:nodoc:
|
9
|
+
autoload :SolrInstrumentation, File.join(File.dirname(__FILE__), 'rails', 'solr_instrumentation')
|
9
10
|
autoload :StubSessionProxy, File.join(File.dirname(__FILE__), 'rails', 'stub_session_proxy')
|
10
|
-
|
11
|
-
|
11
|
+
begin
|
12
|
+
require 'sunspot_solr'
|
13
|
+
autoload :Server, File.join(File.dirname(__FILE__), 'rails', 'server')
|
14
|
+
rescue LoadError => e
|
15
|
+
# We're fine
|
16
|
+
end
|
12
17
|
|
13
18
|
class <<self
|
14
19
|
attr_writer :configuration
|
@@ -22,7 +27,9 @@ module Sunspot #:nodoc:
|
|
22
27
|
end
|
23
28
|
|
24
29
|
def build_session(configuration = self.configuration)
|
25
|
-
if configuration.
|
30
|
+
if configuration.disabled?
|
31
|
+
StubSessionProxy.new(Sunspot.session)
|
32
|
+
elsif configuration.has_master?
|
26
33
|
SessionProxy::MasterSlaveSessionProxy.new(
|
27
34
|
SessionProxy::ThreadLocalSessionProxy.new(master_config(configuration)),
|
28
35
|
SessionProxy::ThreadLocalSessionProxy.new(slave_config(configuration))
|
@@ -47,9 +54,9 @@ module Sunspot #:nodoc:
|
|
47
54
|
def slave_config(sunspot_rails_configuration)
|
48
55
|
config = Sunspot::Configuration.build
|
49
56
|
config.solr.url = URI::HTTP.build(
|
50
|
-
:host =>
|
51
|
-
:port =>
|
52
|
-
:path =>
|
57
|
+
:host => sunspot_rails_configuration.hostname,
|
58
|
+
:port => sunspot_rails_configuration.port,
|
59
|
+
:path => sunspot_rails_configuration.path
|
53
60
|
).to_s
|
54
61
|
config
|
55
62
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
1
3
|
module Sunspot #:nodoc:
|
2
4
|
module Rails #:nodoc:
|
3
5
|
#
|
@@ -12,6 +14,8 @@ module Sunspot #:nodoc:
|
|
12
14
|
# min_memory: 512M
|
13
15
|
# max_memory: 1G
|
14
16
|
# solr_jar: /some/path/solr15/start.jar
|
17
|
+
# bind_address: 0.0.0.0
|
18
|
+
# disabled: false
|
15
19
|
# test:
|
16
20
|
# solr:
|
17
21
|
# hostname: localhost
|
@@ -193,9 +197,10 @@ module Sunspot #:nodoc:
|
|
193
197
|
@data_path ||= user_configuration_from_key('solr', 'data_path') || File.join(::Rails.root, 'solr', 'data', ::Rails.env)
|
194
198
|
end
|
195
199
|
|
196
|
-
def
|
197
|
-
@
|
200
|
+
def pid_dir
|
201
|
+
@pid_dir ||= user_configuration_from_key('solr', 'pid_dir') || File.join(::Rails.root, 'solr', 'pids', ::Rails.env)
|
198
202
|
end
|
203
|
+
|
199
204
|
|
200
205
|
#
|
201
206
|
# The solr home directory. Sunspot::Rails expects this directory
|
@@ -235,7 +240,22 @@ module Sunspot #:nodoc:
|
|
235
240
|
def max_memory
|
236
241
|
@max_memory ||= user_configuration_from_key('solr', 'max_memory')
|
237
242
|
end
|
238
|
-
|
243
|
+
|
244
|
+
#
|
245
|
+
# Interface on which to run Solr
|
246
|
+
#
|
247
|
+
def bind_address
|
248
|
+
@bind_address ||= user_configuration_from_key('solr', 'bind_address')
|
249
|
+
end
|
250
|
+
|
251
|
+
#
|
252
|
+
# Whether or not to disable Solr.
|
253
|
+
# Defaults to false.
|
254
|
+
#
|
255
|
+
def disabled?
|
256
|
+
@disabled ||= (user_configuration_from_key('disabled') || false)
|
257
|
+
end
|
258
|
+
|
239
259
|
private
|
240
260
|
|
241
261
|
#
|
@@ -277,7 +297,8 @@ module Sunspot #:nodoc:
|
|
277
297
|
path = File.join(::Rails.root, 'config', 'sunspot.yml')
|
278
298
|
if File.exist?(path)
|
279
299
|
File.open(path) do |file|
|
280
|
-
|
300
|
+
processed = ERB.new(file.read).result
|
301
|
+
YAML.load(processed)[::Rails.env]
|
281
302
|
end
|
282
303
|
else
|
283
304
|
{}
|