supernova 0.6.5 → 0.6.6

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/Gemfile CHANGED
@@ -10,6 +10,7 @@ gem "rsolr"
10
10
  gem "will_paginate"
11
11
  gem "json"
12
12
  gem "activesupport"
13
+ gem "typhoeus"
13
14
 
14
15
  group :development do
15
16
  gem "i18n"
@@ -29,6 +29,7 @@ GEM
29
29
  json (1.5.3)
30
30
  linecache (0.46)
31
31
  rbx-require-relative (> 0.0.4)
32
+ mime-types (1.16)
32
33
  mysql2 (0.2.11)
33
34
  rake (0.9.2)
34
35
  rbx-require-relative (0.0.5)
@@ -48,6 +49,9 @@ GEM
48
49
  ruby-debug-base (~> 0.10.4.0)
49
50
  ruby-debug-base (0.10.4)
50
51
  linecache (>= 0.3)
52
+ typhoeus (0.2.4)
53
+ mime-types
54
+ mime-types
51
55
  tzinfo (0.3.29)
52
56
  will_paginate (2.3.15)
53
57
 
@@ -70,4 +74,5 @@ DEPENDENCIES
70
74
  rsolr
71
75
  rspec (~> 2.3.0)
72
76
  ruby-debug
77
+ typhoeus
73
78
  will_paginate
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.5
1
+ 0.6.6
@@ -1,9 +1,10 @@
1
1
  require "json"
2
2
  require "fileutils"
3
3
  require "time"
4
+ require "typhoeus"
4
5
 
5
6
  class Supernova::SolrIndexer
6
- attr_accessor :options, :db, :ids, :max_rows_to_direct_index, :local_solr
7
+ attr_accessor :options, :db, :ids, :max_rows_to_direct_index, :local_solr, :current_json_string
7
8
  attr_writer :index_file_path, :debug
8
9
 
9
10
  MAX_ROWS_TO_DIRECT_INDEX = 100
@@ -221,7 +222,7 @@ class Supernova::SolrIndexer
221
222
  end
222
223
  if self.max_rows_to_direct_index < rows.count
223
224
  debug "indexed #{rows.length} rows with json in %TIME%" do
224
- index_with_json_file(rows)
225
+ index_with_json(rows)
225
226
  end
226
227
  else
227
228
  debug "indexed #{rows.length} rows directly in %TIME%" do
@@ -230,6 +231,10 @@ class Supernova::SolrIndexer
230
231
  end
231
232
  end
232
233
 
234
+ def index_with_json(rows)
235
+ options && options[:use_json_file] ? index_with_json_file(rows) : index_with_json_string(rows)
236
+ end
237
+
233
238
  def solr_rows_to_index_for_query(query)
234
239
  query_db(query).map do |row|
235
240
  map_for_solr(row)
@@ -257,6 +262,36 @@ class Supernova::SolrIndexer
257
262
  finish
258
263
  end
259
264
 
265
+ def append_to_json_string(row)
266
+ if self.current_json_string.nil?
267
+ self.current_json_string = "\{\n"
268
+ else
269
+ self.current_json_string << ",\n"
270
+ end
271
+ self.current_json_string << %("add":#{{:doc => row}.to_json})
272
+ end
273
+
274
+ def finalize_json_string
275
+ self.current_json_string << "\n}"
276
+ end
277
+
278
+ def post_json_string
279
+ Typhoeus::Request.post("#{solr_update_url}?commit=true",
280
+ :body => self.current_json_string,
281
+ :headers => { "Content-type" => "application/json; charset=utf-8" }
282
+ ).tap do |response|
283
+ self.current_json_string = nil
284
+ end
285
+ end
286
+
287
+ def index_with_json_string(rows)
288
+ rows.each do |row|
289
+ append_to_json_string(row)
290
+ end
291
+ finalize_json_string
292
+ post_json_string
293
+ end
294
+
260
295
  def ids_given?
261
296
  self.ids.is_a?(Array)
262
297
  end
@@ -297,10 +332,14 @@ class Supernova::SolrIndexer
297
332
  Supernova::Solr.url.present? ? Supernova::Solr.url.to_s.gsub(/\/$/, "") : nil
298
333
  end
299
334
 
335
+ def solr_update_url
336
+ "#{solr_url}/update/json"
337
+ end
338
+
300
339
  def do_index_file(options = {})
301
340
  raise "solr not configured" if solr_url.nil?
302
341
  cmd = if self.local_solr
303
- %(curl -s '#{solr_url}/update/json?commit=true\\&stream.file=#{index_file_path}')
342
+ %(curl -s '#{solr_update_url}?commit=true\\&stream.file=#{index_file_path}')
304
343
  else
305
344
  %(cd #{File.dirname(index_file_path)} && curl -s '#{solr_url}/update/json?commit=true' --data-binary @#{File.basename(index_file_path)} -H 'Content-type:application/json')
306
345
  end
@@ -31,6 +31,21 @@ describe "Solr" do
31
31
  Offer.search_scope
32
32
  end
33
33
 
34
+ describe "#index_with_json_string" do
35
+ it "indexes the correct rows" do
36
+ Supernova::Solr.truncate!
37
+ indexer = Supernova::SolrIndexer.new
38
+ indexer.index_with_json_string([
39
+ { :title_s => "Title1", :id => 1, :type => "Record" },
40
+ { :title_s => "Title2", :id => 2, :type => "Record" }
41
+ ]
42
+ )
43
+ response = Supernova::Solr.connection.get('select', :params => { :q=>'*:*', :start=>0, :rows=>10, :sort => "id asc" })
44
+ response["response"]["docs"].first.should == { "title_s" => "Title1", "id" => "1", "type" => "Record" }
45
+ response["response"]["docs"].at(1).should == { "title_s" => "Title2", "id" => "2", "type" => "Record" }
46
+ end
47
+ end
48
+
34
49
  describe "#indexing" do
35
50
  before(:each) do
36
51
  Supernova::Solr.truncate!
@@ -64,6 +79,7 @@ describe "Solr" do
64
79
  offer1 = Offer.create!(:user_id => 1, :popularity => 10)
65
80
  offer2 = Offer.create!(:user_id => 2, :popularity => 20)
66
81
  indexer = OfferIndex.new(:db => ActiveRecord::Base.connection, :max_rows_to_direct_index => 0)
82
+ indexer.options[:use_json_file] = true
67
83
  indexer.index!
68
84
  indexer.instance_variable_get("@index_file_path").should_not be_nil
69
85
  OfferIndex.search_scope.total_entries.should == 2
@@ -76,6 +92,7 @@ describe "Solr" do
76
92
  offer1 = Offer.create!(:user_id => 1, :popularity => 10)
77
93
  offer2 = Offer.create!(:user_id => 2, :popularity => 20)
78
94
  indexer = OfferIndex.new(:db => ActiveRecord::Base.connection, :max_rows_to_direct_index => 0, :local_solr => true)
95
+ indexer.options[:use_json_file] = true
79
96
  indexer.index!
80
97
  indexer.instance_variable_get("@index_file_path").should_not be_nil
81
98
  OfferIndex.search_scope.first.instance_variable_get("@original_search_doc")["indexed_at_dt"].should_not be_nil
@@ -33,6 +33,72 @@ describe Supernova::SolrIndexer do
33
33
  Kernel.stub!(:`).and_return true
34
34
  end
35
35
 
36
+ describe "#index_with_json_string" do
37
+ let(:row1) { double("row1") }
38
+ let(:row2) { double("row2") }
39
+ let(:rows) { [row1, row2] }
40
+
41
+ before(:each) do
42
+ indexer.current_json_string = "{"
43
+ indexer.stub!(:append_to_json_string)
44
+ end
45
+
46
+ it "calls append to string with all rows" do
47
+ indexer.should_receive(:append_to_json_string).with(row1)
48
+ indexer.should_receive(:append_to_json_string).with(row2)
49
+ indexer.index_with_json_string(rows)
50
+ end
51
+
52
+ it "calls finalize_json_string" do
53
+ indexer.should_receive(:finalize_json_string)
54
+ indexer.index_with_json_string(rows)
55
+ end
56
+
57
+ it "calls post_json_string" do
58
+ indexer.should_receive(:post_json_string)
59
+ indexer.index_with_json_string(rows)
60
+ end
61
+ end
62
+
63
+ describe "#post_json_string" do
64
+ before(:each) do
65
+ Typhoeus::Request.stub(:post)
66
+ end
67
+
68
+ it "posts the json string" do
69
+ indexer.current_json_string = "some string"
70
+ Typhoeus::Request.should_receive(:post).with("http://solr.xx:9333/solr/update/json?commit=true", :body => "some string", :headers => { "Content-type" => "application/json; charset=utf-8" }).and_return(double("rsp", :body => "text"))
71
+ indexer.post_json_string
72
+ end
73
+
74
+ it "resets the current_json_string" do
75
+ indexer.current_json_string = "some string"
76
+ indexer.post_json_string
77
+ indexer.current_json_string.should be_nil
78
+ end
79
+ end
80
+
81
+ describe "#append_to_json_string" do
82
+ it "creates a new string" do
83
+ indexer.append_to_json_string({"a" => 1})
84
+ indexer.current_json_string.should == %({\n"add":{"doc":{"a":1}})
85
+ end
86
+
87
+ it "appends to the existing string" do
88
+ indexer.append_to_json_string({"a" => 1})
89
+ indexer.append_to_json_string({"b" => 2})
90
+ indexer.current_json_string.should == %({\n"add":{"doc":{"a":1}},\n"add":{"doc":{"b":2}})
91
+ end
92
+ end
93
+
94
+ describe "#finalize_json_string" do
95
+ it "adds the last brackets" do
96
+ indexer.append_to_json_string({"a" => 1})
97
+ indexer.finalize_json_string
98
+ indexer.current_json_string.should == %({\n"add":{"doc":{"a":1}}\n})
99
+ end
100
+ end
101
+
36
102
  describe "initialize" do
37
103
  it "sets all options" do
38
104
  options = { :database => { :database => "dynasty", :username => "dynasty_user" } }
@@ -375,6 +441,19 @@ describe Supernova::SolrIndexer do
375
441
  end
376
442
  end
377
443
 
444
+ describe "#index_with_json" do
445
+ it "calls index_with_json_string by default" do
446
+ indexer.should_receive(:index_with_json_string).with([1])
447
+ indexer.index_with_json([1])
448
+ end
449
+
450
+ it "calls index_with_json_file when asked to" do
451
+ indexer.options[:use_json_file] = true
452
+ indexer.should_receive(:index_with_json_file).with([1])
453
+ indexer.index_with_json([1])
454
+ end
455
+ end
456
+
378
457
  describe "#index_rows" do
379
458
  let(:row1) { double("row1") }
380
459
  let(:row2) { double("row2") }
@@ -404,7 +483,7 @@ describe Supernova::SolrIndexer do
404
483
 
405
484
  it "calls map_directly when number of rows < max_rows_to_direct_index" do
406
485
  custom_indexer.should_receive(:max_rows_to_direct_index).and_return 1
407
- custom_indexer.should_receive(:index_with_json_file).with([mapped1, mapped2])
486
+ custom_indexer.should_receive(:index_with_json).with([mapped1, mapped2])
408
487
  custom_indexer.index_rows([row1, row2])
409
488
  end
410
489
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{supernova}
8
- s.version = "0.6.5"
8
+ s.version = "0.6.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tobias Schwab"]
12
- s.date = %q{2011-09-01}
12
+ s.date = %q{2011-11-04}
13
13
  s.default_executable = %q{start_solr}
14
14
  s.description = %q{Unified search scopes}
15
15
  s.email = %q{tobias.schwab@dynport.de}
@@ -95,7 +95,7 @@ Gem::Specification.new do |s|
95
95
  s.homepage = %q{http://github.com/dynport/supernova}
96
96
  s.licenses = ["MIT"]
97
97
  s.require_paths = ["lib"]
98
- s.rubygems_version = %q{1.6.2}
98
+ s.rubygems_version = %q{1.5.2}
99
99
  s.summary = %q{Unified search scopes}
100
100
 
101
101
  if s.respond_to? :specification_version then
@@ -106,6 +106,7 @@ Gem::Specification.new do |s|
106
106
  s.add_runtime_dependency(%q<will_paginate>, [">= 0"])
107
107
  s.add_runtime_dependency(%q<json>, [">= 0"])
108
108
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
109
+ s.add_runtime_dependency(%q<typhoeus>, [">= 0"])
109
110
  s.add_development_dependency(%q<i18n>, [">= 0"])
110
111
  s.add_development_dependency(%q<activerecord>, ["~> 3.0.7"])
111
112
  s.add_development_dependency(%q<ruby-debug>, [">= 0"])
@@ -123,6 +124,7 @@ Gem::Specification.new do |s|
123
124
  s.add_dependency(%q<will_paginate>, [">= 0"])
124
125
  s.add_dependency(%q<json>, [">= 0"])
125
126
  s.add_dependency(%q<activesupport>, [">= 0"])
127
+ s.add_dependency(%q<typhoeus>, [">= 0"])
126
128
  s.add_dependency(%q<i18n>, [">= 0"])
127
129
  s.add_dependency(%q<activerecord>, ["~> 3.0.7"])
128
130
  s.add_dependency(%q<ruby-debug>, [">= 0"])
@@ -141,6 +143,7 @@ Gem::Specification.new do |s|
141
143
  s.add_dependency(%q<will_paginate>, [">= 0"])
142
144
  s.add_dependency(%q<json>, [">= 0"])
143
145
  s.add_dependency(%q<activesupport>, [">= 0"])
146
+ s.add_dependency(%q<typhoeus>, [">= 0"])
144
147
  s.add_dependency(%q<i18n>, [">= 0"])
145
148
  s.add_dependency(%q<activerecord>, ["~> 3.0.7"])
146
149
  s.add_dependency(%q<ruby-debug>, [">= 0"])
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: supernova
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 5
10
- version: 0.6.5
9
+ - 6
10
+ version: 0.6.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tobias Schwab
@@ -15,12 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-01 00:00:00 +02:00
18
+ date: 2011-11-04 00:00:00 +01:00
19
19
  default_executable: start_solr
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  name: rsolr
23
- prerelease: false
24
23
  version_requirements: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
@@ -30,11 +29,11 @@ dependencies:
30
29
  segments:
31
30
  - 0
32
31
  version: "0"
32
+ prerelease: false
33
33
  type: :runtime
34
34
  requirement: *id001
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: will_paginate
37
- prerelease: false
38
37
  version_requirements: &id002 !ruby/object:Gem::Requirement
39
38
  none: false
40
39
  requirements:
@@ -44,11 +43,11 @@ dependencies:
44
43
  segments:
45
44
  - 0
46
45
  version: "0"
46
+ prerelease: false
47
47
  type: :runtime
48
48
  requirement: *id002
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: json
51
- prerelease: false
52
51
  version_requirements: &id003 !ruby/object:Gem::Requirement
53
52
  none: false
54
53
  requirements:
@@ -58,11 +57,11 @@ dependencies:
58
57
  segments:
59
58
  - 0
60
59
  version: "0"
60
+ prerelease: false
61
61
  type: :runtime
62
62
  requirement: *id003
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: activesupport
65
- prerelease: false
66
65
  version_requirements: &id004 !ruby/object:Gem::Requirement
67
66
  none: false
68
67
  requirements:
@@ -72,11 +71,11 @@ dependencies:
72
71
  segments:
73
72
  - 0
74
73
  version: "0"
74
+ prerelease: false
75
75
  type: :runtime
76
76
  requirement: *id004
77
77
  - !ruby/object:Gem::Dependency
78
- name: i18n
79
- prerelease: false
78
+ name: typhoeus
80
79
  version_requirements: &id005 !ruby/object:Gem::Requirement
81
80
  none: false
82
81
  requirements:
@@ -86,12 +85,26 @@ dependencies:
86
85
  segments:
87
86
  - 0
88
87
  version: "0"
89
- type: :development
88
+ prerelease: false
89
+ type: :runtime
90
90
  requirement: *id005
91
91
  - !ruby/object:Gem::Dependency
92
- name: activerecord
93
- prerelease: false
92
+ name: i18n
94
93
  version_requirements: &id006 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ prerelease: false
103
+ type: :development
104
+ requirement: *id006
105
+ - !ruby/object:Gem::Dependency
106
+ name: activerecord
107
+ version_requirements: &id007 !ruby/object:Gem::Requirement
95
108
  none: false
96
109
  requirements:
97
110
  - - ~>
@@ -102,12 +115,12 @@ dependencies:
102
115
  - 0
103
116
  - 7
104
117
  version: 3.0.7
118
+ prerelease: false
105
119
  type: :development
106
- requirement: *id006
120
+ requirement: *id007
107
121
  - !ruby/object:Gem::Dependency
108
122
  name: ruby-debug
109
- prerelease: false
110
- version_requirements: &id007 !ruby/object:Gem::Requirement
123
+ version_requirements: &id008 !ruby/object:Gem::Requirement
111
124
  none: false
112
125
  requirements:
113
126
  - - ">="
@@ -116,12 +129,12 @@ dependencies:
116
129
  segments:
117
130
  - 0
118
131
  version: "0"
132
+ prerelease: false
119
133
  type: :development
120
- requirement: *id007
134
+ requirement: *id008
121
135
  - !ruby/object:Gem::Dependency
122
136
  name: mysql2
123
- prerelease: false
124
- version_requirements: &id008 !ruby/object:Gem::Requirement
137
+ version_requirements: &id009 !ruby/object:Gem::Requirement
125
138
  none: false
126
139
  requirements:
127
140
  - - ~>
@@ -132,12 +145,12 @@ dependencies:
132
145
  - 2
133
146
  - 7
134
147
  version: 0.2.7
148
+ prerelease: false
135
149
  type: :development
136
- requirement: *id008
150
+ requirement: *id009
137
151
  - !ruby/object:Gem::Dependency
138
152
  name: ZenTest
139
- prerelease: false
140
- version_requirements: &id009 !ruby/object:Gem::Requirement
153
+ version_requirements: &id010 !ruby/object:Gem::Requirement
141
154
  none: false
142
155
  requirements:
143
156
  - - "="
@@ -148,12 +161,12 @@ dependencies:
148
161
  - 5
149
162
  - 0
150
163
  version: 4.5.0
164
+ prerelease: false
151
165
  type: :development
152
- requirement: *id009
166
+ requirement: *id010
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: geokit
155
- prerelease: false
156
- version_requirements: &id010 !ruby/object:Gem::Requirement
169
+ version_requirements: &id011 !ruby/object:Gem::Requirement
157
170
  none: false
158
171
  requirements:
159
172
  - - ">="
@@ -162,12 +175,12 @@ dependencies:
162
175
  segments:
163
176
  - 0
164
177
  version: "0"
178
+ prerelease: false
165
179
  type: :development
166
- requirement: *id010
180
+ requirement: *id011
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: autotest
169
- prerelease: false
170
- version_requirements: &id011 !ruby/object:Gem::Requirement
183
+ version_requirements: &id012 !ruby/object:Gem::Requirement
171
184
  none: false
172
185
  requirements:
173
186
  - - ">="
@@ -176,12 +189,12 @@ dependencies:
176
189
  segments:
177
190
  - 0
178
191
  version: "0"
192
+ prerelease: false
179
193
  type: :development
180
- requirement: *id011
194
+ requirement: *id012
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: autotest-growl
183
- prerelease: false
184
- version_requirements: &id012 !ruby/object:Gem::Requirement
197
+ version_requirements: &id013 !ruby/object:Gem::Requirement
185
198
  none: false
186
199
  requirements:
187
200
  - - ">="
@@ -190,12 +203,12 @@ dependencies:
190
203
  segments:
191
204
  - 0
192
205
  version: "0"
206
+ prerelease: false
193
207
  type: :development
194
- requirement: *id012
208
+ requirement: *id013
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: rspec
197
- prerelease: false
198
- version_requirements: &id013 !ruby/object:Gem::Requirement
211
+ version_requirements: &id014 !ruby/object:Gem::Requirement
199
212
  none: false
200
213
  requirements:
201
214
  - - ~>
@@ -206,12 +219,12 @@ dependencies:
206
219
  - 3
207
220
  - 0
208
221
  version: 2.3.0
222
+ prerelease: false
209
223
  type: :development
210
- requirement: *id013
224
+ requirement: *id014
211
225
  - !ruby/object:Gem::Dependency
212
226
  name: bundler
213
- prerelease: false
214
- version_requirements: &id014 !ruby/object:Gem::Requirement
227
+ version_requirements: &id015 !ruby/object:Gem::Requirement
215
228
  none: false
216
229
  requirements:
217
230
  - - ~>
@@ -222,12 +235,12 @@ dependencies:
222
235
  - 0
223
236
  - 0
224
237
  version: 1.0.0
238
+ prerelease: false
225
239
  type: :development
226
- requirement: *id014
240
+ requirement: *id015
227
241
  - !ruby/object:Gem::Dependency
228
242
  name: jeweler
229
- prerelease: false
230
- version_requirements: &id015 !ruby/object:Gem::Requirement
243
+ version_requirements: &id016 !ruby/object:Gem::Requirement
231
244
  none: false
232
245
  requirements:
233
246
  - - ~>
@@ -238,12 +251,12 @@ dependencies:
238
251
  - 6
239
252
  - 0
240
253
  version: 1.6.0
254
+ prerelease: false
241
255
  type: :development
242
- requirement: *id015
256
+ requirement: *id016
243
257
  - !ruby/object:Gem::Dependency
244
258
  name: rcov
245
- prerelease: false
246
- version_requirements: &id016 !ruby/object:Gem::Requirement
259
+ version_requirements: &id017 !ruby/object:Gem::Requirement
247
260
  none: false
248
261
  requirements:
249
262
  - - ">="
@@ -252,8 +265,9 @@ dependencies:
252
265
  segments:
253
266
  - 0
254
267
  version: "0"
268
+ prerelease: false
255
269
  type: :development
256
- requirement: *id016
270
+ requirement: *id017
257
271
  description: Unified search scopes
258
272
  email: tobias.schwab@dynport.de
259
273
  executables:
@@ -366,7 +380,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
366
380
  requirements: []
367
381
 
368
382
  rubyforge_project:
369
- rubygems_version: 1.6.2
383
+ rubygems_version: 1.5.2
370
384
  signing_key:
371
385
  specification_version: 3
372
386
  summary: Unified search scopes