supernova 0.6.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
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