supernova 0.3.12 → 0.3.13
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bin/start_solr +3 -0
- data/lib/supernova.rb +13 -0
- data/lib/supernova/criteria.rb +19 -4
- data/lib/supernova/solr_criteria.rb +4 -13
- data/lib/supernova/solr_indexer.rb +34 -4
- data/lib/supernova/thinking_sphinx_criteria.rb +1 -1
- data/spec/integration/solr_spec.rb +64 -40
- data/spec/supernova/criteria_spec.rb +74 -10
- data/spec/supernova/solr_criteria_spec.rb +16 -18
- data/spec/supernova/solr_indexer_spec.rb +128 -12
- data/spec/supernova_spec.rb +41 -0
- data/supernova.gemspec +4 -2
- metadata +7 -6
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.13
|
data/bin/start_solr
ADDED
data/lib/supernova.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require "rsolr"
|
2
|
+
require "active_support/core_ext/object/blank"
|
3
|
+
require "active_support/core_ext/hash"
|
2
4
|
|
3
5
|
module Supernova
|
4
6
|
KM_TO_METER = 1000.0
|
@@ -21,6 +23,17 @@ module Supernova
|
|
21
23
|
self.defined_named_search_scopes << name
|
22
24
|
end
|
23
25
|
end
|
26
|
+
|
27
|
+
class << self
|
28
|
+
def build_ar_like_record(clazz, attributes, original_search_doc = nil)
|
29
|
+
record = clazz.new
|
30
|
+
record.instance_variable_set("@attributes", attributes)
|
31
|
+
record.instance_variable_set("@readonly", true)
|
32
|
+
record.instance_variable_set("@new_record", false)
|
33
|
+
record.instance_variable_set("@original_search_doc", original_search_doc) if original_search_doc
|
34
|
+
record
|
35
|
+
end
|
36
|
+
end
|
24
37
|
end
|
25
38
|
|
26
39
|
require "supernova/numeric_extensions"
|
data/lib/supernova/criteria.rb
CHANGED
@@ -2,7 +2,7 @@ class Supernova::Criteria
|
|
2
2
|
DEFAULT_PER_PAGE = 25
|
3
3
|
FIRST_PAGE = 1
|
4
4
|
|
5
|
-
attr_accessor :filters, :search_options, :clazz
|
5
|
+
attr_accessor :filters, :search_options, :clazz, :results
|
6
6
|
|
7
7
|
class << self
|
8
8
|
def method_missing(*args)
|
@@ -138,8 +138,22 @@ class Supernova::Criteria
|
|
138
138
|
def to_parameters
|
139
139
|
implement_in_subclass
|
140
140
|
end
|
141
|
-
|
141
|
+
|
142
|
+
def populate
|
143
|
+
@results = execute if !populated?
|
144
|
+
self
|
145
|
+
end
|
146
|
+
|
142
147
|
def to_a
|
148
|
+
populate
|
149
|
+
results
|
150
|
+
end
|
151
|
+
|
152
|
+
def populated?
|
153
|
+
instance_variables.include?("@results")
|
154
|
+
end
|
155
|
+
|
156
|
+
def execute
|
143
157
|
implement_in_subclass
|
144
158
|
end
|
145
159
|
|
@@ -170,8 +184,9 @@ class Supernova::Criteria
|
|
170
184
|
end
|
171
185
|
|
172
186
|
def method_missing(*args, &block)
|
173
|
-
if
|
174
|
-
|
187
|
+
if Supernova::Collection.instance_methods.include?(args.first.to_s)
|
188
|
+
populate
|
189
|
+
@results.send(*args, &block)
|
175
190
|
elsif self.named_scope_defined?(args.first)
|
176
191
|
self.merge(self.search_options[:named_scope_class].send(*args)) # merge named scope and current criteria
|
177
192
|
else
|
@@ -87,20 +87,11 @@ class Supernova::SolrCriteria < Supernova::Criteria
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def build_doc(hash)
|
90
|
-
|
91
|
-
|
92
|
-
doc.instance_variable_set("@solr_doc", hash)
|
93
|
-
atts = convert_doc_attributes(hash)
|
94
|
-
if doc.instance_variables.include?("@attributes")
|
95
|
-
doc.instance_variable_set("@attributes", atts.except("type"))
|
90
|
+
if hash["type"].respond_to?(:constantize)
|
91
|
+
Supernova.build_ar_like_record(hash["type"].constantize, convert_doc_attributes(hash), hash)
|
96
92
|
else
|
97
|
-
|
98
|
-
doc.send(:"#{key}=", value) if doc.respond_to?(:"#{key}=")
|
99
|
-
end
|
93
|
+
hash
|
100
94
|
end
|
101
|
-
doc.instance_variable_set("@readonly", true)
|
102
|
-
doc.instance_variable_set("@new_record", false)
|
103
|
-
doc
|
104
95
|
end
|
105
96
|
|
106
97
|
# called in build doc, all hashes have strings as keys!!!
|
@@ -137,7 +128,7 @@ class Supernova::SolrCriteria < Supernova::Criteria
|
|
137
128
|
end
|
138
129
|
end
|
139
130
|
|
140
|
-
def
|
131
|
+
def execute
|
141
132
|
response = Supernova::Solr.connection.post("select", :data => to_params)
|
142
133
|
collection = Supernova::Collection.new(current_page, per_page, response["response"]["numFound"])
|
143
134
|
collection.replace(build_docs(response["response"]["docs"]))
|
@@ -72,14 +72,43 @@ class Supernova::SolrIndexer
|
|
72
72
|
|
73
73
|
def index!
|
74
74
|
index_query(query_to_index) do |row|
|
75
|
-
|
75
|
+
map_for_solr(row)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def map_for_solr(row)
|
80
|
+
map_hash_keys_to_solr(
|
81
|
+
if self.respond_to?(:extra_attributes_from_record) && self.class.clazz
|
82
|
+
row.merge(self.extra_attributes_from_record(Supernova.build_ar_like_record(self.class.clazz, row)).stringify_keys)
|
83
|
+
elsif self.respond_to?(:row_to_solr)
|
84
|
+
puts "DEPRECATION WARNING: use before_index instead of row_to_solr! in #{caller.first}"
|
85
|
+
self.row_to_solr(row)
|
86
|
+
else
|
87
|
+
self.before_index(row)
|
88
|
+
end
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
def before_index(row)
|
80
93
|
row
|
81
94
|
end
|
82
95
|
|
96
|
+
def map_hash_keys_to_solr(hash)
|
97
|
+
hash["indexed_at_dt"] = Time.now.utc.iso8601
|
98
|
+
hash["id_s"] = [self.class.table_name, hash["id"]].compact.join("/") if hash["id"]
|
99
|
+
self.class.field_definitions.each do |field, options|
|
100
|
+
if value = hash.delete(field.to_s)
|
101
|
+
if options[:type] == :date
|
102
|
+
value = Time.utc(value.year, value.month, value.day) if value.is_a?(Date)
|
103
|
+
value = value.utc.iso8601
|
104
|
+
end
|
105
|
+
hash["#{field}_#{self.class.suffix_from_type(options[:type])}"] = value
|
106
|
+
end
|
107
|
+
end
|
108
|
+
hash["type"] = self.class.clazz.to_s if self.class.clazz
|
109
|
+
hash
|
110
|
+
end
|
111
|
+
|
83
112
|
def table_name
|
84
113
|
self.class.table_name || (self.class.clazz && self.class.clazz.respond_to?(:table_name) ? self.class.clazz.table_name : nil)
|
85
114
|
end
|
@@ -99,7 +128,7 @@ class Supernova::SolrIndexer
|
|
99
128
|
|
100
129
|
def defined_fields
|
101
130
|
self.class.field_definitions.map do |field, options|
|
102
|
-
|
131
|
+
field.to_s if options[:virtual] != true
|
103
132
|
end.compact
|
104
133
|
end
|
105
134
|
|
@@ -219,7 +248,8 @@ class Supernova::SolrIndexer
|
|
219
248
|
%(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')
|
220
249
|
end
|
221
250
|
out = Kernel.send(:`, cmd)
|
222
|
-
|
251
|
+
raise "unable to index #{index_file_path}: #{out}" if !out.to_s.include?(%(<int name=\"status\">0</int>))
|
252
|
+
FileUtils.rm_f(self.index_file_path)
|
223
253
|
out
|
224
254
|
end
|
225
255
|
end
|
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
describe "Solr" do
|
4
4
|
before(:each) do
|
5
5
|
Supernova::Solr.instance_variable_set("@connection", nil)
|
6
|
-
Supernova::Solr.url = "http://localhost:
|
6
|
+
Supernova::Solr.url = "http://localhost:8985/solr/"
|
7
7
|
Supernova::Solr.truncate!
|
8
8
|
Offer.criteria_class = Supernova::SolrCriteria
|
9
9
|
root = Geokit::LatLng.new(47, 11)
|
@@ -41,7 +41,7 @@ describe "Solr" do
|
|
41
41
|
has :user_id, :type => :integer
|
42
42
|
has :popularity, :type => :integer
|
43
43
|
|
44
|
-
def
|
44
|
+
def before_index(row)
|
45
45
|
row["indexed_at_dt"] = Time.now.utc.iso8601
|
46
46
|
row
|
47
47
|
end
|
@@ -54,9 +54,9 @@ describe "Solr" do
|
|
54
54
|
offer2 = Offer.create!(:user_id => 2, :popularity => 20)
|
55
55
|
indexer = OfferIndex.new(:db => ActiveRecord::Base.connection)
|
56
56
|
indexer.index!
|
57
|
-
OfferIndex.search_scope.
|
58
|
-
OfferIndex.search_scope.
|
59
|
-
OfferIndex.search_scope.order("user_id desc").
|
57
|
+
OfferIndex.search_scope.first.instance_variable_get("@original_search_doc")["indexed_at_dt"].should_not be_nil
|
58
|
+
OfferIndex.search_scope.total_entries.should == 2
|
59
|
+
OfferIndex.search_scope.order("user_id desc").populate.results.should == [offer2, offer1]
|
60
60
|
indexer.instance_variable_get("@index_file_path").should be_nil
|
61
61
|
end
|
62
62
|
|
@@ -66,9 +66,9 @@ describe "Solr" do
|
|
66
66
|
indexer = OfferIndex.new(:db => ActiveRecord::Base.connection, :max_rows_to_direct_index => 0)
|
67
67
|
indexer.index!
|
68
68
|
indexer.instance_variable_get("@index_file_path").should_not be_nil
|
69
|
-
OfferIndex.search_scope.
|
70
|
-
OfferIndex.search_scope.
|
71
|
-
OfferIndex.search_scope.order("user_id desc").
|
69
|
+
OfferIndex.search_scope.total_entries.should == 2
|
70
|
+
OfferIndex.search_scope.first.instance_variable_get("@original_search_doc")["indexed_at_dt"].should_not be_nil
|
71
|
+
OfferIndex.search_scope.order("user_id desc").populate.results.should == [offer2, offer1]
|
72
72
|
File.should_not be_exists(indexer.instance_variable_get("@index_file_path"))
|
73
73
|
end
|
74
74
|
|
@@ -78,39 +78,63 @@ describe "Solr" do
|
|
78
78
|
indexer = OfferIndex.new(:db => ActiveRecord::Base.connection, :max_rows_to_direct_index => 0, :local_solr => true)
|
79
79
|
indexer.index!
|
80
80
|
indexer.instance_variable_get("@index_file_path").should_not be_nil
|
81
|
-
OfferIndex.search_scope.
|
82
|
-
OfferIndex.search_scope.
|
83
|
-
OfferIndex.search_scope.order("user_id desc").
|
81
|
+
OfferIndex.search_scope.first.instance_variable_get("@original_search_doc")["indexed_at_dt"].should_not be_nil
|
82
|
+
OfferIndex.search_scope.total_entries.should == 2
|
83
|
+
OfferIndex.search_scope.order("user_id desc").populate.results.should == [offer2, offer1]
|
84
84
|
File.should_not be_exists(indexer.instance_variable_get("@index_file_path"))
|
85
85
|
end
|
86
|
+
|
87
|
+
describe "with extra_attributes_from_doc method defined" do
|
88
|
+
|
89
|
+
class OfferIndexWitheExtraSearchMethodFromDoc < Supernova::SolrIndexer
|
90
|
+
has :user_id, :type => :integer
|
91
|
+
has :popularity, :type => :integer
|
92
|
+
has :upcased_text, :type => :text, :virtual => true
|
93
|
+
has :text, :type => :text
|
94
|
+
|
95
|
+
clazz Offer
|
96
|
+
|
97
|
+
def extra_attributes_from_record(record)
|
98
|
+
{ :upcased_text => record.text.to_s.upcase.presence }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it "sets the capitalize_text attribute" do
|
103
|
+
Offer.create!(:user_id => 2, :popularity => 20, :text => "lower_text")
|
104
|
+
indexer = OfferIndexWitheExtraSearchMethodFromDoc.new(:db => ActiveRecord::Base.connection)
|
105
|
+
indexer.index!
|
106
|
+
offer = OfferIndexWitheExtraSearchMethodFromDoc.search_scope.first
|
107
|
+
offer.instance_variable_get("@original_search_doc")["upcased_text_t"].should == "LOWER_TEXT"
|
108
|
+
end
|
109
|
+
end
|
86
110
|
end
|
87
111
|
|
88
112
|
describe "searching" do
|
89
113
|
it "returns the correct current_page when nil" do
|
90
|
-
new_criteria.
|
114
|
+
new_criteria.current_page.should == 1
|
91
115
|
end
|
92
116
|
|
93
117
|
it "returns the correct page when set" do
|
94
|
-
new_criteria.paginate(:page => 10).
|
118
|
+
new_criteria.paginate(:page => 10).current_page.should == 10
|
95
119
|
end
|
96
120
|
|
97
121
|
it "the correct per_page when set" do
|
98
|
-
new_criteria.paginate(:per_page => 10).
|
122
|
+
new_criteria.paginate(:per_page => 10).per_page.should == 10
|
99
123
|
end
|
100
124
|
|
101
125
|
it "the correct per_page when not set" do
|
102
|
-
new_criteria.
|
126
|
+
new_criteria.per_page.should == 25
|
103
127
|
end
|
104
128
|
|
105
129
|
describe "plain text search" do
|
106
130
|
it "returns the correct entries for 1 term" do
|
107
|
-
new_criteria.search("text_t:Hans").
|
108
|
-
new_criteria.search("text_t:Hans").search("text_t:Meyer").
|
109
|
-
new_criteria.search("text_t:Marek").
|
131
|
+
new_criteria.search("text_t:Hans").map { |h| h["id"] }.should == [1]
|
132
|
+
new_criteria.search("text_t:Hans").search("text_t:Meyer").map { |h| h["id"] }.should == [1]
|
133
|
+
new_criteria.search("text_t:Marek").map { |h| h["id"] }.should == [2]
|
110
134
|
end
|
111
135
|
|
112
136
|
it "returns the correct options for a combined search" do
|
113
|
-
new_criteria.search("text_t:Hans", "text_t:Marek").
|
137
|
+
new_criteria.search("text_t:Hans", "text_t:Marek").populate.results.should == []
|
114
138
|
end
|
115
139
|
end
|
116
140
|
|
@@ -119,14 +143,14 @@ describe "Solr" do
|
|
119
143
|
"popularity_i" => 10, "location_p" => "47,11"
|
120
144
|
}.each do |key, value|
|
121
145
|
it "sets #{key} to #{value}" do
|
122
|
-
doc = new_criteria.search("text_t:Hans").
|
146
|
+
doc = new_criteria.search("text_t:Hans").first.instance_variable_get("@original_search_doc")[key].should == value
|
123
147
|
end
|
124
148
|
end
|
125
149
|
|
126
150
|
describe "nearby search" do
|
127
151
|
{ 49.kms => 1, 51.kms => 2 }.each do |distance, total_entries|
|
128
152
|
it "returns #{total_entries} for distance #{distance}" do
|
129
|
-
new_criteria.attribute_mapping(:location => { :type => :location }).near(47, 11).within(distance).
|
153
|
+
new_criteria.attribute_mapping(:location => { :type => :location }).near(47, 11).within(distance).total_entries.should == total_entries
|
130
154
|
end
|
131
155
|
end
|
132
156
|
end
|
@@ -145,25 +169,25 @@ describe "Solr" do
|
|
145
169
|
:type => "Offer"
|
146
170
|
)
|
147
171
|
Supernova::Solr.connection.commit
|
148
|
-
raise "There should be 3 docs" if new_criteria.
|
149
|
-
new_criteria.with(:user_id_i.not => nil).
|
172
|
+
raise "There should be 3 docs" if new_criteria.total_entries != 3
|
173
|
+
new_criteria.with(:user_id_i.not => nil).map { |h| h["id"] }.should == [1, 2]
|
150
174
|
end
|
151
175
|
|
152
176
|
it "finds the correct values for not specific value" do
|
153
|
-
new_criteria.with(:user_id_i.not => 1).
|
177
|
+
new_criteria.with(:user_id_i.not => 1).map { |h| h["id"] }.should == [2]
|
154
178
|
end
|
155
179
|
end
|
156
180
|
|
157
181
|
describe "gt and lt searches" do
|
158
182
|
{ :gt => [2], :gte => [1, 2], :lt => [], :lte => [1] }.each do |type, ids|
|
159
183
|
it "finds ids #{ids.inspect} for #{type}" do
|
160
|
-
new_criteria.with(:user_id_i.send(type) => 1).
|
184
|
+
new_criteria.with(:user_id_i.send(type) => 1).map { |row| row["id"] }.sort.should == ids
|
161
185
|
end
|
162
186
|
end
|
163
187
|
end
|
164
188
|
|
165
189
|
it "returns the correct objects" do
|
166
|
-
new_criteria.with(:user_id_i => 1).
|
190
|
+
new_criteria.with(:user_id_i => 1).first.should be_an_instance_of(Offer)
|
167
191
|
end
|
168
192
|
|
169
193
|
{ :id => 1, :user_id => 1, :enabled => false, :text => "Hans Meyer", :popularity => 10 }.each do |key, value|
|
@@ -173,45 +197,45 @@ describe "Solr" do
|
|
173
197
|
:enabled => { :type => :boolean },
|
174
198
|
:popularity => { :type => :integer },
|
175
199
|
:text => { :type => :text}
|
176
|
-
).with(:id => "offers/1").
|
200
|
+
).with(:id => "offers/1").first
|
177
201
|
doc.send(key).should == value
|
178
202
|
end
|
179
203
|
end
|
180
204
|
|
181
205
|
it "combines filters" do
|
182
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => false).
|
183
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => true).
|
206
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).total_entries.should == 1
|
207
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => true).total_entries.should == 0
|
184
208
|
end
|
185
209
|
|
186
210
|
it "uses without correctly" do
|
187
|
-
new_criteria.without(:user_id_i => 1).
|
188
|
-
new_criteria.without(:user_id_i => 2).
|
189
|
-
new_criteria.without(:user_id_i => 2).without(:user_id_i => 1).
|
211
|
+
new_criteria.without(:user_id_i => 1).map(&:id).should == [2]
|
212
|
+
new_criteria.without(:user_id_i => 2).map(&:id).should == [1]
|
213
|
+
new_criteria.without(:user_id_i => 2).without(:user_id_i => 1).map(&:id).should == []
|
190
214
|
end
|
191
215
|
|
192
216
|
it "uses the correct orders" do
|
193
|
-
new_criteria.order("id desc").
|
194
|
-
new_criteria.order("id asc").
|
217
|
+
new_criteria.order("id desc").map(&:id).should == [2, 1]
|
218
|
+
new_criteria.order("id asc").map(&:id).should == [1, 2]
|
195
219
|
end
|
196
220
|
|
197
221
|
it "uses the correct pagination attributes" do
|
198
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => false).
|
222
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).total_entries.should == 1
|
199
223
|
new_criteria.with(:user_id_i => 1, :enabled_b => false).length.should == 1
|
200
|
-
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).
|
224
|
+
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).total_entries.should == 1
|
201
225
|
new_criteria.with(:user_id_i => 1, :enabled_b => false).paginate(:page => 10).length.should == 0
|
202
226
|
|
203
|
-
new_criteria.paginate(:per_page => 1, :page => 1).
|
204
|
-
new_criteria.paginate(:per_page => 1, :page => 2).
|
227
|
+
new_criteria.paginate(:per_page => 1, :page => 1).map(&:id).should == [1]
|
228
|
+
new_criteria.paginate(:per_page => 1, :page => 2).map(&:id).should == [2]
|
205
229
|
end
|
206
230
|
|
207
231
|
it "handels empty results correctly" do
|
208
|
-
results = new_criteria.with(:user_id_i => 1, :enabled_b => true)
|
232
|
+
results = new_criteria.with(:user_id_i => 1, :enabled_b => true)
|
209
233
|
results.total_entries.should == 0
|
210
234
|
results.current_page.should == 1
|
211
235
|
end
|
212
236
|
|
213
237
|
it "only sets specific attributes" do
|
214
|
-
results = new_criteria.select(:user_id_i).with(:user_id_i => 1)
|
238
|
+
results = new_criteria.select(:user_id_i).with(:user_id_i => 1)
|
215
239
|
results.length.should == 1
|
216
240
|
results.first.should == { "id" => "offers/1", "user_id_i" => 1 }
|
217
241
|
end
|
@@ -3,7 +3,9 @@ require "ostruct"
|
|
3
3
|
|
4
4
|
describe "Supernova::Criteria" do
|
5
5
|
let(:scope) { Supernova::Criteria.new }
|
6
|
-
|
6
|
+
before(:each) do
|
7
|
+
scope.stub!(:execute).and_return [].paginate(:page => 1)
|
8
|
+
end
|
7
9
|
|
8
10
|
describe "#initialize" do
|
9
11
|
it "can be initialized" do
|
@@ -110,11 +112,68 @@ describe "Supernova::Criteria" do
|
|
110
112
|
end
|
111
113
|
|
112
114
|
it "to_a raises an implement in subclass error" do
|
115
|
+
scope.unstub(:execute)
|
113
116
|
lambda {
|
114
|
-
scope.
|
117
|
+
scope.execute
|
115
118
|
}.should raise_error("implement in subclass")
|
116
119
|
end
|
117
120
|
|
121
|
+
describe "#to_a" do
|
122
|
+
it "calls populate" do
|
123
|
+
scope.should_receive(:populate)
|
124
|
+
scope.to_a
|
125
|
+
end
|
126
|
+
|
127
|
+
it "returns the results" do
|
128
|
+
res = double("results")
|
129
|
+
scope.instance_variable_set("@results", res)
|
130
|
+
scope.to_a.should == res
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#populate" do
|
135
|
+
it "returns self when" do
|
136
|
+
scope.stub!(:populated?).and_return true
|
137
|
+
scope.populate.should == scope
|
138
|
+
end
|
139
|
+
|
140
|
+
it "does not change @results when already populated" do
|
141
|
+
res = double("results")
|
142
|
+
scope.instance_variable_set("@results", res)
|
143
|
+
scope.stub!(:populated?).and_return true
|
144
|
+
scope.populate.should == scope
|
145
|
+
scope.instance_variable_get("@results").should == res
|
146
|
+
end
|
147
|
+
|
148
|
+
it "returns the scope when not populated yet" do
|
149
|
+
scope.populate.should == scope
|
150
|
+
end
|
151
|
+
|
152
|
+
it "calls execute" do
|
153
|
+
scope.should_receive(:execute).and_return []
|
154
|
+
scope.populate
|
155
|
+
end
|
156
|
+
|
157
|
+
it "assigns the result of populate" do
|
158
|
+
result = double("result")
|
159
|
+
scope.stub!(:execute).and_return result
|
160
|
+
scope.populate
|
161
|
+
scope.instance_variable_get("@results").should == result
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "#populated?" do
|
166
|
+
it "returns false when @results not set" do
|
167
|
+
scope.should_not be_populated
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns true when instance variable set" do
|
171
|
+
scope.stub!(:execute).and_return []
|
172
|
+
scope.populate
|
173
|
+
scope.should be_populated
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
118
177
|
describe "with to_a stubbed" do
|
119
178
|
let(:array_double) { double("array") }
|
120
179
|
|
@@ -122,17 +181,19 @@ describe "Supernova::Criteria" do
|
|
122
181
|
scope.stub!(:to_a).and_return array_double
|
123
182
|
end
|
124
183
|
|
125
|
-
[ :first, :each, :count, :last ].each do |method|
|
184
|
+
[ :first, :each, :count, :last, :total_entries ].each do |method|
|
126
185
|
it "forwards #{method} to array" do
|
127
|
-
|
128
|
-
|
186
|
+
results = double("ret")
|
187
|
+
scope.instance_variable_set("@results", results)
|
188
|
+
scope.should_receive(:populated?).and_return false
|
129
189
|
scope.send(method)
|
130
190
|
end
|
131
191
|
end
|
132
192
|
|
133
193
|
it "hands given blocks in" do
|
134
194
|
array = [1, 2, 3]
|
135
|
-
scope.
|
195
|
+
scope.instance_variable_set("@results", array)
|
196
|
+
scope.stub!(:populated?).and_return true
|
136
197
|
called = []
|
137
198
|
scope.each do |i|
|
138
199
|
called << i
|
@@ -155,6 +216,13 @@ describe "Supernova::Criteria" do
|
|
155
216
|
}.should raise_error(NoMethodError)
|
156
217
|
end
|
157
218
|
|
219
|
+
it "forwards all array methods to @results" do
|
220
|
+
results = double("results")
|
221
|
+
scope.instance_variable_set("@results", results)
|
222
|
+
results.should_receive(:index, "1")
|
223
|
+
scope.index("1")
|
224
|
+
end
|
225
|
+
|
158
226
|
it "calls named_scope_defined" do
|
159
227
|
scope.should_receive(:named_scope_defined?).with(:rgne).and_return false
|
160
228
|
scope.method_missing(:rgne) rescue nil
|
@@ -195,10 +263,6 @@ describe "Supernova::Criteria" do
|
|
195
263
|
end
|
196
264
|
end
|
197
265
|
|
198
|
-
describe "#with_scopes" do
|
199
|
-
|
200
|
-
end
|
201
|
-
|
202
266
|
describe "#merge" do
|
203
267
|
let(:criteria) { Supernova::Criteria.new.order("popularity asc").with(:a => 1).conditions(:b => 2).search("New Search") }
|
204
268
|
let(:new_crit) { Supernova::Criteria.new.order("popularity desc").with(:c => 8).conditions(:e => 9).search("Search") }
|
@@ -163,7 +163,7 @@ describe Supernova::SolrCriteria do
|
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
166
|
-
describe "#
|
166
|
+
describe "#execute" do
|
167
167
|
let(:params) { double("params") }
|
168
168
|
|
169
169
|
before(:each) do
|
@@ -173,45 +173,45 @@ describe Supernova::SolrCriteria do
|
|
173
173
|
|
174
174
|
it "calls to_params" do
|
175
175
|
criteria.should_receive(:to_params).and_return params
|
176
|
-
criteria.
|
176
|
+
criteria.execute
|
177
177
|
end
|
178
178
|
|
179
179
|
it "calls get with select and params" do
|
180
180
|
rsolr.should_receive(:post).with("select", :data => params).and_return solr_response
|
181
|
-
criteria.
|
181
|
+
criteria.execute
|
182
182
|
end
|
183
183
|
|
184
184
|
it "returns a Supernova::Collection" do
|
185
|
-
criteria.
|
185
|
+
criteria.execute.should be_an_instance_of(Supernova::Collection)
|
186
186
|
end
|
187
187
|
|
188
188
|
it "sets the correct page when page is nil" do
|
189
|
-
criteria.
|
189
|
+
criteria.execute.current_page.should == 1
|
190
190
|
end
|
191
191
|
|
192
192
|
it "sets the correct page when page is 1" do
|
193
|
-
criteria.paginate(:page => 1).
|
193
|
+
criteria.paginate(:page => 1).execute.current_page.should == 1
|
194
194
|
end
|
195
195
|
|
196
196
|
it "sets the correct page when page is 2" do
|
197
|
-
criteria.paginate(:page => 2).
|
197
|
+
criteria.paginate(:page => 2).execute.current_page.should == 2
|
198
198
|
end
|
199
199
|
|
200
200
|
it "sets the correct per_page when zero" do
|
201
|
-
criteria.paginate(:page => 2, :per_page => nil).
|
201
|
+
criteria.paginate(:page => 2, :per_page => nil).execute.per_page.should == 25
|
202
202
|
end
|
203
203
|
|
204
204
|
it "sets the custom per_page when given" do
|
205
|
-
criteria.paginate(:page => 2, :per_page => 10).
|
205
|
+
criteria.paginate(:page => 2, :per_page => 10).execute.per_page.should == 10
|
206
206
|
end
|
207
207
|
|
208
208
|
it "sets the correct total_entries" do
|
209
|
-
criteria.paginate(:page => 2, :per_page => 10).
|
209
|
+
criteria.paginate(:page => 2, :per_page => 10).execute.total_entries.should == 2
|
210
210
|
end
|
211
211
|
|
212
212
|
it "calls build_docs with returned docs" do
|
213
213
|
criteria.should_receive(:build_docs).with(docs).and_return []
|
214
|
-
criteria.
|
214
|
+
criteria.execute
|
215
215
|
end
|
216
216
|
|
217
217
|
it "calls replace on collection wit returned docs" do
|
@@ -220,7 +220,7 @@ describe Supernova::SolrCriteria do
|
|
220
220
|
built_docs = double("built docs")
|
221
221
|
criteria.stub!(:build_docs).and_return built_docs
|
222
222
|
col.should_receive(:replace).with(built_docs)
|
223
|
-
criteria.
|
223
|
+
criteria.execute
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
@@ -283,9 +283,7 @@ describe Supernova::SolrCriteria do
|
|
283
283
|
criteria.build_doc(row).should == row
|
284
284
|
end
|
285
285
|
|
286
|
-
it "assigns the attributes returned from convert_doc_attributes to attributes when
|
287
|
-
str = String.new
|
288
|
-
str.instance_variable_set("@attributes", {})
|
286
|
+
it "assigns the attributes returned from convert_doc_attributes to attributes when record responds to attributes=" do
|
289
287
|
atts = { :title => "Hello" }
|
290
288
|
row = { "type" => "Offer" }
|
291
289
|
criteria.should_receive(:convert_doc_attributes).with(row).and_return atts
|
@@ -293,9 +291,9 @@ describe Supernova::SolrCriteria do
|
|
293
291
|
doc.instance_variable_get("@attributes").should == atts
|
294
292
|
end
|
295
293
|
|
296
|
-
it "sets the original
|
297
|
-
|
298
|
-
criteria.build_doc(
|
294
|
+
it "sets the original original_search_doc" do
|
295
|
+
original_search_doc = { "type" => "Offer", "id" => "offers/id" }
|
296
|
+
criteria.build_doc(original_search_doc).instance_variable_get("@original_search_doc").should == original_search_doc
|
299
297
|
end
|
300
298
|
|
301
299
|
it "should be readonly" do
|
@@ -6,11 +6,13 @@ describe Supernova::SolrIndexer do
|
|
6
6
|
let(:to_index) { { :id => 1, :title => "Some Title"} }
|
7
7
|
let(:file_stub) { double("file").as_null_object }
|
8
8
|
let(:solr) { double("solr").as_null_object }
|
9
|
+
let(:solr_index_response) { %(<int name="status">0</int>) }
|
9
10
|
|
10
11
|
let(:indexer) do
|
11
12
|
indexer = Supernova::SolrIndexer.new
|
12
13
|
indexer.db = db
|
13
14
|
indexer.stub!(:system).and_return true
|
15
|
+
Kernel.stub!(:`).and_return solr_index_response
|
14
16
|
indexer
|
15
17
|
end
|
16
18
|
|
@@ -68,17 +70,81 @@ describe Supernova::SolrIndexer do
|
|
68
70
|
indexer.index!
|
69
71
|
end
|
70
72
|
|
71
|
-
it "calls
|
73
|
+
it "calls map_for_solr with all returned rows from sql" do
|
72
74
|
row1 = double("row1")
|
73
75
|
row2 = double("row2")
|
74
76
|
indexer.stub!(:query).and_return [row1, row2]
|
75
77
|
indexer.stub!(:query_to_index).and_return "some query"
|
76
|
-
indexer.should_receive(:
|
78
|
+
indexer.should_receive(:map_for_solr).with(row1)
|
77
79
|
indexer.stub!(:index_query).and_yield(row1)
|
78
80
|
indexer.index!
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
84
|
+
describe "#map_for_solr" do
|
85
|
+
let(:row) { { "a" => 1 } }
|
86
|
+
|
87
|
+
before(:each) do
|
88
|
+
indexer.stub!(:puts)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "calls row_to_solr" do
|
92
|
+
indexer.should_not_receive(:before_index)
|
93
|
+
indexer.should_receive(:row_to_solr).with(row).and_return row
|
94
|
+
indexer.map_for_solr(row)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "prints a deprecation warning when using row_to_solr" do
|
98
|
+
indexer.stub!(:row_to_solr).with(row).and_return row
|
99
|
+
indexer.should_receive(:puts).with(/DEPRECATION WARNING: use before_index instead of row_to_solr! in/)
|
100
|
+
indexer.map_for_solr(row)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "calls before_index when row_to_solr is not defined" do
|
104
|
+
row = { "a" => 1 }
|
105
|
+
indexer.should_receive(:before_index).with(row).and_return row
|
106
|
+
indexer.map_for_solr(row)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "calls map_hash_keys_to_solr with result of row_to_solr" do
|
110
|
+
dummy_row = double("dummy row")
|
111
|
+
indexer.stub!(:row_to_solr).and_return dummy_row
|
112
|
+
indexer.should_receive(:map_hash_keys_to_solr).with(dummy_row)
|
113
|
+
indexer.map_for_solr({ "a" => 1 })
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "with the index defining extra_attributes_from_record" do
|
117
|
+
let(:index) { SolrOfferIndex.new }
|
118
|
+
let(:offer_double) { double("Solr Offer", :id => 88).as_null_object }
|
119
|
+
|
120
|
+
class SolrOfferIndex < Supernova::SolrIndexer
|
121
|
+
clazz Offer
|
122
|
+
has :created_at, :type => :date
|
123
|
+
has :offer_id, :type => :integer
|
124
|
+
|
125
|
+
def extra_attributes_from_record(doc)
|
126
|
+
{ :offer_code => "OFFER_#{doc.id}" }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it "calls Supernova.build_ar_like_record with correct parameters" do
|
131
|
+
Supernova.should_receive(:build_ar_like_record).and_return offer_double
|
132
|
+
SolrOfferIndex.new("offer_id" => 77, "type" => "Offer").map_for_solr(row)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "includes the original attributes" do
|
136
|
+
index = SolrOfferIndex.new
|
137
|
+
index.map_for_solr({ "a" => 2 })["a"].should == 2
|
138
|
+
end
|
139
|
+
|
140
|
+
it "includes the attributes from extra_attributes_from_record" do
|
141
|
+
index = SolrOfferIndex.new
|
142
|
+
index.map_for_solr({ "a" => 2, "id" => "88" })["offer_code"].should == "OFFER_88"
|
143
|
+
hash = { :a => 1, "a" => 2 }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
82
148
|
describe "validate_lat" do
|
83
149
|
{ nil => nil, 10 => 10.0, 90.1 => nil, 90 => 90, -90.1 => nil, -90 => -90 }.each do |from, to|
|
84
150
|
it "converts #{from} to #{to}" do
|
@@ -118,9 +184,9 @@ describe Supernova::SolrIndexer do
|
|
118
184
|
end
|
119
185
|
end
|
120
186
|
|
121
|
-
describe "#
|
187
|
+
describe "#before_index" do
|
122
188
|
it "returns the db row by default" do
|
123
|
-
indexer.
|
189
|
+
indexer.before_index("id" => 1).should == { "id" => 1 }
|
124
190
|
end
|
125
191
|
end
|
126
192
|
|
@@ -138,6 +204,56 @@ describe Supernova::SolrIndexer do
|
|
138
204
|
end
|
139
205
|
end
|
140
206
|
|
207
|
+
describe "#map_hash_keys_to_solr" do
|
208
|
+
class CustomSolrIndex < Supernova::SolrIndexer
|
209
|
+
has :offer_id, :type => :integer
|
210
|
+
has :lat, :type => :float
|
211
|
+
has :lng, :type => :float
|
212
|
+
has :created_at, :type => :date
|
213
|
+
has :checkin_date, :type => :date
|
214
|
+
end
|
215
|
+
|
216
|
+
it "maps float fields" do
|
217
|
+
index = CustomSolrIndex.new
|
218
|
+
index.map_hash_keys_to_solr("lat" => 49.0)["lat_f"].should == 49.0
|
219
|
+
end
|
220
|
+
|
221
|
+
it "maps time fields to iso8601" do
|
222
|
+
index = CustomSolrIndex.new
|
223
|
+
time = Time.parse("2011-02-03 11:20:30")
|
224
|
+
index.map_hash_keys_to_solr("created_at" => time)["created_at_dt"].should == "2011-02-03T10:20:30Z"
|
225
|
+
end
|
226
|
+
|
227
|
+
it "maps date fields to iso8601" do
|
228
|
+
date = Date.new(2011, 1, 2)
|
229
|
+
CustomSolrIndex.new.map_hash_keys_to_solr("checkin_date" => date)["checkin_date_dt"].should == "2011-01-02T00:00:00Z"
|
230
|
+
end
|
231
|
+
|
232
|
+
it "sets the indexed_at time" do
|
233
|
+
Time.stub!(:now).and_return Time.parse("2011-02-03T11:20:30Z")
|
234
|
+
CustomSolrIndex.new.map_hash_keys_to_solr({})["indexed_at_dt"].should == "2011-02-03T11:20:30Z"
|
235
|
+
Time.unstub!(:now)
|
236
|
+
end
|
237
|
+
|
238
|
+
it "adds the class as type when class set" do
|
239
|
+
clazz = Class.new(Supernova::SolrIndexer)
|
240
|
+
clazz.clazz Offer
|
241
|
+
clazz.new.map_hash_keys_to_solr({})["type"].should == "Offer"
|
242
|
+
end
|
243
|
+
|
244
|
+
it "uses the table_name as prefix for ids" do
|
245
|
+
clazz = Class.new(Supernova::SolrIndexer)
|
246
|
+
clazz.table_name :people
|
247
|
+
clazz.new.map_hash_keys_to_solr({ "id" => 88 })["id_s"].should == "people/88"
|
248
|
+
end
|
249
|
+
|
250
|
+
it "adds the sets the cla" do
|
251
|
+
clazz = Class.new(Supernova::SolrIndexer)
|
252
|
+
clazz.clazz Offer
|
253
|
+
clazz.new.map_hash_keys_to_solr({})["type"].should == "Offer"
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
141
257
|
describe "#index_query" do
|
142
258
|
let(:query) { %(SELECT CONCAT("user_", id) AS id, title FROM people WHERE type = 'User') }
|
143
259
|
|
@@ -300,13 +416,13 @@ describe Supernova::SolrIndexer do
|
|
300
416
|
|
301
417
|
it "calls the correct curl command" do
|
302
418
|
indexer = Supernova::SolrIndexer.new(:index_file_path => "/tmp/some_path.json", :local_solr => true)
|
303
|
-
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return
|
419
|
+
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return solr_index_response
|
304
420
|
indexer.do_index_file(:local => true)
|
305
421
|
end
|
306
422
|
|
307
423
|
it "calls rm on file" do
|
308
424
|
indexer = Supernova::SolrIndexer.new(:index_file_path => "/tmp/some_path.json", :local_solr => true)
|
309
|
-
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return
|
425
|
+
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return solr_index_response
|
310
426
|
FileUtils.should_receive(:rm_f).with("/tmp/some_path.json")
|
311
427
|
indexer.do_index_file(:local => true)
|
312
428
|
end
|
@@ -315,13 +431,15 @@ describe Supernova::SolrIndexer do
|
|
315
431
|
indexer = Supernova::SolrIndexer.new(:index_file_path => "/tmp/some_path.json", :local_solr => true)
|
316
432
|
Kernel.should_receive(:`).with("curl -s 'http://solr.xx:9333/solr/update/json?commit=true\\&stream.file=/tmp/some_path.json'").and_return %(<int name="status">1</int>)
|
317
433
|
FileUtils.should_not_receive(:rm_f).with("/tmp/some_path.json")
|
318
|
-
|
434
|
+
lambda {
|
435
|
+
indexer.do_index_file(:local => true)
|
436
|
+
}.should raise_error
|
319
437
|
end
|
320
438
|
|
321
439
|
it "executes the correct curl call when not local" do
|
322
440
|
# curl 'http://localhost:8983/solr/update/json?commit=true' --data-binary @books.json -H 'Content-type:application/json'
|
323
441
|
indexer.index_file_path = "/tmp/some_path.json"
|
324
|
-
Kernel.should_receive(:`).with("cd /tmp && curl -s 'http://solr.xx:9333/solr/update/json?commit=true' --data-binary @some_path.json -H 'Content-type:application/json'")
|
442
|
+
Kernel.should_receive(:`).with("cd /tmp && curl -s 'http://solr.xx:9333/solr/update/json?commit=true' --data-binary @some_path.json -H 'Content-type:application/json'").and_return solr_index_response
|
325
443
|
indexer.do_index_file
|
326
444
|
end
|
327
445
|
end
|
@@ -394,9 +512,7 @@ describe Supernova::SolrIndexer do
|
|
394
512
|
custom_indexer.defined_fields
|
395
513
|
end
|
396
514
|
|
397
|
-
["title
|
398
|
-
%(IF(created_at IS NULL, NULL, CONCAT(REPLACE(created_at, " ", "T"), "Z")) AS created_at_dt)
|
399
|
-
].each do |field|
|
515
|
+
["title", "artist_id", "description", "created_at"].each do |field|
|
400
516
|
it "includes field #{field.inspect}" do
|
401
517
|
custom_indexer.defined_fields.should include(field)
|
402
518
|
end
|
@@ -406,7 +522,7 @@ describe Supernova::SolrIndexer do
|
|
406
522
|
clazz = Class.new(Supernova::SolrIndexer)
|
407
523
|
clazz.has :location, :type => :location, :virtual => true
|
408
524
|
clazz.has :title, :type => :string
|
409
|
-
clazz.new.defined_fields.should == ["title
|
525
|
+
clazz.new.defined_fields.should == ["title"]
|
410
526
|
end
|
411
527
|
end
|
412
528
|
|
data/spec/supernova_spec.rb
CHANGED
@@ -84,4 +84,45 @@ describe Supernova do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
87
|
+
|
88
|
+
describe "#build_ar_like_record" do
|
89
|
+
let(:offer_double) { double("offer").as_null_object }
|
90
|
+
|
91
|
+
before(:each) do
|
92
|
+
Offer.stub!(:new).and_return offer_double
|
93
|
+
end
|
94
|
+
|
95
|
+
it "is callable" do
|
96
|
+
Supernova.should respond_to(:build_ar_like_record)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "creates a new instance" do
|
100
|
+
Offer.should_receive(:new).and_return offer_double
|
101
|
+
Supernova.build_ar_like_record(Offer, {})
|
102
|
+
end
|
103
|
+
|
104
|
+
it "sets the attributes" do
|
105
|
+
atts = { :a => 1 }
|
106
|
+
offer_double.should_receive(:instance_variable_set).with("@attributes", atts)
|
107
|
+
Supernova.build_ar_like_record(Offer, atts)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "returns the record" do
|
111
|
+
Supernova.build_ar_like_record(Offer, {}).should == offer_double
|
112
|
+
end
|
113
|
+
|
114
|
+
it "sets readonly to true" do
|
115
|
+
Supernova.build_ar_like_record(Offer, {}).instance_variable_get("@readonly").should == true
|
116
|
+
end
|
117
|
+
|
118
|
+
it "sets new_record to false" do
|
119
|
+
Supernova.build_ar_like_record(Offer, {}).instance_variable_get("@new_record").should == false
|
120
|
+
end
|
121
|
+
|
122
|
+
it "sets the original_search_doc hash when given" do
|
123
|
+
original_search_doc = double("original_search_doc")
|
124
|
+
doc = Supernova.build_ar_like_record(Offer, {}, original_search_doc)
|
125
|
+
doc.instance_variable_get("@original_search_doc").should == original_search_doc
|
126
|
+
end
|
127
|
+
end
|
87
128
|
end
|
data/supernova.gemspec
CHANGED
@@ -5,13 +5,14 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{supernova}
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.13"
|
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-06-
|
12
|
+
s.date = %q{2011-06-29}
|
13
13
|
s.description = %q{Unified search scopes}
|
14
14
|
s.email = %q{tobias.schwab@dynport.de}
|
15
|
+
s.executables = ["start_solr"]
|
15
16
|
s.extra_rdoc_files = [
|
16
17
|
"LICENSE.txt",
|
17
18
|
"README.rdoc"
|
@@ -27,6 +28,7 @@ Gem::Specification.new do |s|
|
|
27
28
|
"Rakefile",
|
28
29
|
"VERSION",
|
29
30
|
"autotest/discover.rb",
|
31
|
+
"bin/start_solr",
|
30
32
|
"lib/supernova.rb",
|
31
33
|
"lib/supernova/collection.rb",
|
32
34
|
"lib/supernova/condition.rb",
|
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:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 13
|
10
|
+
version: 0.3.13
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tobias Schwab
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-06-
|
18
|
+
date: 2011-06-29 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
requirement: &id001 !ruby/object:Gem::Requirement
|
@@ -211,8 +211,8 @@ dependencies:
|
|
211
211
|
type: :development
|
212
212
|
description: Unified search scopes
|
213
213
|
email: tobias.schwab@dynport.de
|
214
|
-
executables:
|
215
|
-
|
214
|
+
executables:
|
215
|
+
- start_solr
|
216
216
|
extensions: []
|
217
217
|
|
218
218
|
extra_rdoc_files:
|
@@ -229,6 +229,7 @@ files:
|
|
229
229
|
- Rakefile
|
230
230
|
- VERSION
|
231
231
|
- autotest/discover.rb
|
232
|
+
- bin/start_solr
|
232
233
|
- lib/supernova.rb
|
233
234
|
- lib/supernova/collection.rb
|
234
235
|
- lib/supernova/condition.rb
|